> ## Documentation Index
> Fetch the complete documentation index at: https://developer.iobot.chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Enviar campaña masiva por plantilla

> Envía una plantilla de WhatsApp a múltiples contactos

Envía una plantilla de WhatsApp a una lista de contactos. Opcionalmente mapea campos de cada contacto a los parámetros dinámicos de la plantilla para personalizar cada mensaje.

## Autenticación

Requiere el encabezado `x-api-key` con el App Key del negocio. Consulta [Autenticación](/authentication).

## Encabezados

<ParamField header="x-api-key" type="string" required>
  App Key del negocio. Consulta [Autenticación](/authentication).
</ParamField>

## Cuerpo de la solicitud

Enviado como JSON.

<ParamField body="contacts_id" type="number[]" required>
  Arreglo de IDs de contactos a quienes se enviará la campaña.
</ParamField>

<ParamField body="contacts" type="object[]" required>
  Arreglo de contactos. Cada objeto debe tener `nombre` y `numero` como campos obligatorios. Puedes incluir cualquier campo adicional y referenciarlo en `paramMapping`.

  ```json theme={null}
  [
    { "nombre": "Juan Pérez", "numero": "5215512345678", "producto": "Plan Pro" }
  ]
  ```
</ParamField>

<ParamField body="plantilla_id" type="number" required>
  ID interno de la plantilla a enviar. Debe pertenecer al negocio indicado en `empresa_id`.
</ParamField>

<ParamField body="empresa_id" type="number" required>
  ID del negocio que ejecuta la campaña.
</ParamField>

<ParamField body="user_id" type="number" required>
  ID del usuario que lanza la campaña.
</ParamField>

<ParamField body="nombre" type="string" required>
  Nombre identificador de la campaña.
</ParamField>

<ParamField body="tags" type="number[]">
  Arreglo de IDs de etiquetas para clasificar los contactos de la campaña. Puede ser vacío.
</ParamField>

<ParamField body="step" type="number" required>
  ID del paso (etapa del embudo) al que se asociará la campaña. Consulta los pasos disponibles con [Obtener Pasos](/campanias/obtener-pasos).
</ParamField>

<ParamField body="paramMapping" type="object">
  Mapeo de los parámetros dinámicos de la plantilla a campos del contacto. La llave corresponde al número de placeholder en la plantilla (`"1"` → `{{1}}`, `"2"` → `{{2}}`, ...) y el valor es el nombre del campo del contacto del que se leerá el valor.

  Es decir: `"2": "producto"` significa "para el placeholder `{{2}}` de la plantilla, usa el valor del campo `producto` de cada contacto". Los números de las llaves no tienen relación con el orden de los campos del contacto.

  Por ejemplo, si tu plantilla dice `Hola {{1}}, tu plan es {{2}}` y envías:

  ```json theme={null}
  "paramMapping": { "1": "nombre", "2": "producto" }
  ```

  Con estos contactos:

  ```json theme={null}
  [
    { "nombre": "Juan Pérez", "numero": "5215512345678", "producto": "Plan Pro" },
    { "nombre": "María López", "numero": "5218112345678", "producto": "Plan Básico" }
  ]
  ```

  Juan recibirá `Hola Juan Pérez, tu plan es Plan Pro` y María recibirá `Hola María López, tu plan es Plan Básico`.

  Si un campo referenciado no existe en el contacto, el parámetro se envía como `"unknown"`. Si omites `paramMapping`, la plantilla se envía sin parámetros.
</ParamField>

## Respuesta

<ResponseField name="success" type="boolean">
  `true` cuando la campaña fue registrada y los mensajes encolados correctamente.
</ResponseField>

<RequestExample>
  ```bash theme={null}
  curl -X POST https://beta.api-iobot-desarrollo.com/chats/enviar/masivo/plantilla \
    -H "Content-Type: application/json" \
    -H "x-api-key: TU_APP_KEY" \
    -d '{
      "contacts_id": [101, 102],
      "contacts": [
        { "nombre": "Juan Pérez", "numero": "5215512345678", "producto": "Plan Pro" },
        { "nombre": "María López", "numero": "5218112345678", "producto": "Plan Básico" }
      ],
      "tags": [],
      "plantilla_id": 123,
      "user_id": 456,
      "empresa_id": 789,
      "step": 3,
      "nombre": "Campaña Mayo 2026",
      "paramMapping": { "1": "nombre", "2": "producto" }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Éxito theme={null}
  {
    "success": true
  }
  ```

  ```json 400 Parámetros inválidos theme={null}
  {
    "success": false,
    "error": "plantilla_id es requerido"
  }
  ```

  ```json 404 Plantilla no encontrada theme={null}
  {
    "success": false,
    "error": "Plantilla no encontrada"
  }
  ```

  ```json 500 Error inesperado theme={null}
  {
    "success": false,
    "error": "Error: ..."
  }
  ```
</ResponseExample>
