Saltar al contenido

Envío de plantilla

Envía una plantilla de mensaje aprobada a través de la API de WhatsApp Business. El servicio resuelve los componentes de la plantilla directamente desde Meta: el payload solo lleva la referencia de la plantilla y los valores de sus variables.

Endpoint: POST /v1/template/messages/{did}

Parámetros

Path

ParámetroTipoRequeridoDescripción
didstringID del destino. Debe coincidir con el did del body.

Body

CampoTipoRequeridoDescripción
didstringID del destino. Igual al del path.
typestringValor fijo template.
channelstringValor fijo WHATSAPP.
templateobject{name, language}: nombre e idioma de la plantilla aprobada. Si no existe esa combinación se devuelve 404.
recipientsarrayLista de destinatarios {to, params}.
campaignIdnumberNoID de campaña (va en camelCase).
client_idnumberNoCliente operador. Requiere permiso BSP_CN cuando difiere del cliente del token.
attendsobjectNo{waitTime, typification}. Ver Attends.
message_send_ttl_secondsnumberNoTiempo de validez del mensaje en segundos.
componentobjectNoHeader de imagen, video, documento o ubicación. Obligatorio cuando la plantilla usa ese tipo de header; el type debe coincidir con el formato del header de la plantilla.

params de cada recipient

Todos los arrays son posicionales: el primer elemento corresponde a {{1}}, el segundo a {{2}}, y así sucesivamente.

CampoTipoDescripción
headerstring[]Valores del placeholder del HEADER TEXT.
bodystring[]Valores de los placeholders del BODY.
buttonsstring[]Valores de los botones que llevan variable (URL dinámica o COPY_CODE), en orden de aparición. Los botones sin variable (QUICK_REPLY, PHONE_NUMBER, URL estática) no se declaran.
productsobject[]Productos para plantillas MPM/SPM.
cardsobject[]Parámetros por tarjeta en carousel: {body, buttons}.

Campos que no se envían

Estos datos los calcula el servicio y no forman parte del payload: namespace (se resuelve de la configuración BSP del DID), los componentes BODY, FOOTER y BUTTONS de la plantilla (se obtienen desde Meta) y el total de contactos (se deduce de recipients). El único componente que se declara en el payload es component.header, para plantillas con header de imagen, video, documento o ubicación. Enviar campos no reconocidos puede romper la request.

Attends

attends configura el comportamiento posterior al envío:

CampoTipoDescripción
waitTimenumberSegundos de espera antes de derivar la atención. En QA se usa -1 para no abrir sesión de atención y 0 para atención inmediata. Si se omite se toma 0.
typificationnumberID interno de tipificación con el que queda clasificada la interacción. 0 = sin tipificación.

Ambos campos son opcionales y se pasan tal cual al motor de despacho: el servicio no los valida ni los calcula.

Request

Los ejemplos usan solo los campos obligatorios más los que cada caso necesita. Recordá que el envío es solo posicional: las plantillas creadas con parameter_format = "named" no pueden enviarse por esta API.

Ejemplo básico

Plantilla de texto con dos variables en el body:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "oferta_cliente",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "body": ["Juan", "30"]
        }
      }
    ]
  }'

Texto simple sin variables

Si la plantilla no tiene placeholders, params se omite:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "horarios_atencion",
      "language": "es"
    },
    "recipients": [
      { "to": "521234567890" }
    ]
  }'

Header de texto + variables

El array header alimenta primero el placeholder del header; el array body, los del body:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "recordatorio_cita",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "header": ["Confirmación de cita"],
          "body": ["Juan", "mañana 10:00"]
        }
      }
    ]
  }'

Header de imagen, video o documento

Para plantillas con header media, component.header lleva el tipo (que debe coincidir con el formato de la plantilla), la URL pública del archivo y su nombre:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "catalogo_imagen",
      "language": "es"
    },
    "component": {
      "header": {
        "type": "image_url",
        "value": "https://cdn.tudominio.com/promo.jpg",
        "filename": "promo.jpg"
      }
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "body": ["Juan"]
        }
      }
    ]
  }'

Para video y documento el formato es igual, con "type": "video_url" o "document_url".

Header de ubicación

Para plantillas con header LOCATION, component.header lleva el objeto location. La ubicación se envía en cada request aunque sea la misma para todos los destinatarios:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "sucursal_cercana",
      "language": "es"
    },
    "component": {
      "header": {
        "type": "location",
        "location": {
          "latitude": "-33.3925562",
          "longitude": "-70.6261222",
          "name": "Chattigo",
          "address": "Av. El Salto 4001, piso 4, Huechuraba, Región Metropolitana"
        }
      }
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "body": ["Juan"]
        }
      }
    ]
  }'

Botón URL con variable

Si el botón URL de la plantilla usa una variable en el link, su valor viaja en buttons:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "seguimiento_pedido",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "body": ["Juan"],
          "buttons": ["12345"]
        }
      }
    ]
  }'

Botón COPY_CODE (código de descuento)

El cupón viaja en buttons como string:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "cupon_bienvenida",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "body": ["Juan"],
          "buttons": ["BIENVENIDO20"]
        }
      }
    ]
  }'

Plantilla de catálogo (MPM)

Para multi-producto, products lleva la acción con el producto destacado y las secciones del catálogo. Los IDs son los product_retailer_id del catálogo de Meta:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "hsm_multiproducto",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "products": [
            {
              "type": "action",
              "action": {
                "thumbnailProductRetailerId": "0003",
                "sections": [
                  {
                    "title": "Ropa y accesorios",
                    "product_items": [
                      { "product_retailer_id": "0064" },
                      { "product_retailer_id": "0042" }
                    ]
                  },
                  {
                    "title": "Comida y bebida",
                    "product_items": [
                      { "product_retailer_id": "0039" }
                    ]
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }'

Para catálogo de producto único (SPM), action lleva solo thumbnailProductRetailerId.

Carousel

Cada tarjeta recibe sus parámetros en cards, en el mismo orden de las tarjetas de la plantilla:

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "template": {
      "name": "carousel_opciones",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": {
          "cards": [
            { "body": ["Tarjeta 1"], "buttons": ["opcion-a"] },
            { "body": ["Tarjeta 2"], "buttons": ["opcion-b"] }
          ]
        }
      }
    ]
  }'

Ejemplo completo con campos opcionales

curl --request POST \
  --url 'https://api.chattigo.com/v1/template/messages/{did}' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "did": "5731000000000",
    "type": "template",
    "channel": "WHATSAPP",
    "campaignId": 3612,
    "client_id": 42,
    "attends": { "waitTime": 5, "typification": 383393 },
    "message_send_ttl_seconds": 3600,
    "template": {
      "name": "oferta_cliente",
      "language": "es"
    },
    "recipients": [
      {
        "to": "521234567890",
        "params": { "body": ["Juan", "30"] }
      }
    ]
  }'

Response

Éxito (200)

{
  "success": true
}

Con warning (ej: campaña o idioma con warning):

{
  "success": true,
  "warning": "..."
}

Errores

CódigoCaso
400did is required o payload inválido
403DID fuera de la jerarquía WABA o client_id sin permiso BSP_CN
404La plantilla no existe para el name/language solicitados
422El did del path no coincide con el del body, o la plantilla es inválida
502Servicio externo inalcanzable (Meta o despacho interno)
  • Solo se pueden enviar plantillas en estado APPROVED.
  • Solo posicional. Los parámetros (header, body, buttons) son []string ordenados y los placeholders deben ser posicionales ({{1}}, {{2}}, …). No se admite parameter_format = "named"; las plantillas named creadas en Meta no pueden enviarse por api-bsp-chattigo.