Enviar plantilla de mensaje

Envía una plantilla de WhatsApp aprobada para iniciar una conversación con un cliente. Si ya existe una conversación abierta, el mensaje se añade a ella; si no, se crea una nueva.

POST https://api.platica.mx/v1/messages/template

Cuerpo de la solicitud

{
  "channelId": "wb-123456789",
  "conversationId": "521234567890",
  "responderAgentId": "agent_123",
  "campaignId": "pV6PvG2lc8ChQb2VmETr",
  "template": {
    "name": "bienvenida_cliente",
    "params": ["Juan", "Premium"],
    "type": "image",
    "file": "https://cdn.assets.com/welcome_image.jpg",
    "buttons": [
      {
        "index": 0,
        "parameters": [{ "type": "text", "text": "promo/enero" }]
      }
    ]
  },
  "client": {
    "name": "José",
    "customFields": {
      "placas": "ABC123",
      "id_recepcion": "REC001"
    }
  }
}

Parámetros del cuerpo

CampoTipoDescripciónRequerido
channelIdstringCanal emisor. Usa preferentemente el prefixedChannelId (por ejemplo wb-123); por compatibilidad se aceptan el teléfono o channelId legacy del agente✓
conversationIdstringNúmero de teléfono del cliente en formato E.164 sin +✓
responderAgentIdstringAgente opcional que atenderá las respuestas. No necesita tener asignado el canal emisor—
campaignIdstringID de la campaña a la que se atribuye el mensaje. Si se omite, el mensaje se registra bajo la campaña api—
template.namestringNombre de la plantilla a utilizar✓
template.paramsarrayVariables para el cuerpo de la plantilla. La cantidad debe coincidir exactamente con el número de variables definidas en la plantilla—
template.typeenumTipo de encabezado: image, document, video. Obligatorio si la plantilla tiene encabezado multimedia—
template.filestringURL pública https:// del archivo para el encabezado. Obligatoria si template.type está presente—
template.buttonsarrayVariables dinámicas de los botones de la plantilla. Máximo 3 elementos—
delaynumberRetraso en milisegundos (3,000 – 86,400,000; máximo 24 horas)—
scheduleTimestringFecha/hora de envío programado (ISO 8601). Máximo 30 días después de la solicitud—
clientobjectInformación del cliente a actualizar (Upsert)—

Canal y agente respondedor

El canal y el agente son independientes:

  • channelId decide desde qué número/canal se envía.
  • responderAgentId decide qué agente atenderá las respuestas.
  • Si omites responderAgentId con un channelId canónico, la conversación nueva queda initiated y sin agente. El defaultAgentId del canal no se hereda (ese campo es solo para inbound).
  • Si usas el identificador legacy (teléfono del agente), se conserva ese agente.
  • Si no hay agente, el mensaje se envía igual. Cuando el contacto responde, el hilo pasa a supervised y sigue sin IA hasta que asignes un agente.
  • Si ya existe una conversación activa para ese contacto y canal, conserva su agente actual.

Cada elemento del array representa un botón dinámico de la plantilla. Los botones estáticos (sin variables) no necesitan incluirse.

CampoTipoDescripciónRequerido
indexintegerÍndice base-0 del botón en la plantilla. Debe corresponder a un botón existente✓
sub_typeenumurl, phone_number, quick_reply, otp. Se infiere automáticamente del tipo definido en la plantilla si se omite—
parametersarrayExactamente un elemento con { "type": "text", "text": "<valor>" }✓

Reglas importantes:

  • Los índices no pueden repetirse dentro del mismo array
  • Para botones de tipo URL, text debe ser un segmento de ruta (ej: "promo/enero"), no una URL completa. Enviar "https://..." devuelve error 400
  • Si sub_type se omite, se infiere del tipo del botón definido en la plantilla (URL → url, OTP → otp, PHONE_NUMBER → phone_number)
"buttons": [
  {
    "index": 0,
    "parameters": [{ "type": "text", "text": "promo/enero" }]
  },
  {
    "index": 1,
    "sub_type": "otp",
    "parameters": [{ "type": "text", "text": "482910" }]
  }
]

Programación

Envía la plantilla inmediatamente, con un retraso o en una fecha específica. Después puedes consultarla, reprogramarla o cancelarla por messageId .

Envío con retraso (delay):

  • Mínimo: 3000 ms (3 segundos)
  • Máximo: 86400000 ms (24 horas)
  • Ejemplo: "delay": 5000 envía el mensaje en 5 segundos

Envío programado (scheduleTime):

  • Formato ISO 8601
  • Debe ser una fecha futura
  • No puede ser más de 30 días después de la solicitud
  • Ejemplos:
    • "2026-10-15T18:40:00" — Hora de México (UTC-6)
    • "2026-10-15T18:40:00Z" — Hora UTC
    • "2026-10-15T18:40:00-06:00" — Con zona horaria específica
CampoTipoDescripción
client.namestringNombre completo del cliente
client.firstnamestringPrimer nombre
client.lastnamestringApellido
client.emailstringCorreo electrónico
client.birthdatestringFecha de nacimiento (dd/mm/yyyy)
client.genderenumGénero: male o female
client.companystringNombre de la compañía
client.countryenumCódigo ISO 3166-1 alpha-2 (ej: MX, US)
client.statestringEstado de residencia
client.citystringCiudad de residencia
client.addressstringDirección completa
client.postalCodestringCódigo postal
client.customFieldsmapObjeto con pares clave-valor de los campos personalizados definidos en el workspace. Consulta Campos personalizados para ver los disponibles.
client.ownersarrayCorreos de usuarios responsables

Validación contra la plantilla

Al recibir la solicitud, el API verifica que el payload sea compatible con la definición de la plantilla registrada en WhatsApp. Si hay incompatibilidades, se devuelve un error 400 con el detalle de cada problema.

Las reglas que se validan automáticamente son:

  • Cantidad de params: debe coincidir exactamente con el número de variables {{1}}, {{2}}... en el cuerpo de la plantilla
  • Encabezado multimedia: si la plantilla tiene encabezado de imagen, video o documento, template.type y template.file son obligatorios y type debe coincidir con el formato definido
  • Índices de botones: cada index en template.buttons debe corresponder a un botón existente en la plantilla
  • Variables de botones URL: el valor de text debe ser un segmento de ruta, no una URL completa
{
  "message": "Template payload is incompatible with template configuration",
  "template": "bienvenida_cliente",
  "errors": [
    {
      "field": "template.params",
      "message": "The number of params does not match the template definition",
      "expected": 2,
      "received": 1
    },
    {
      "field": "template.type",
      "message": "This template requires media header type",
      "expected": "image",
      "received": null,
      "example": {
        "type": "image",
        "file": "https://example.com/your-media-file"
      }
    }
  ]
}

Respuesta

La respuesta varía según si el mensaje se envía de forma inmediata, diferida o programada.

Envío inmediato:

{
  "messageId": "msg_123xyz",
  "status": "sent",
  "timestamp": "2026-09-20T20:00:00Z"
}

Con delay (HTTP 202):

{
  "messageId": "msg_123xyz",
  "kind": "template",
  "status": "delayed",
  "timestamp": "2026-09-20T20:00:00Z",
  "executeAt": "2026-09-20T20:00:05.000Z",
  "delayMs": 5000
}

Con scheduleTime (HTTP 202):

{
  "messageId": "msg_123xyz",
  "kind": "template",
  "status": "scheduled",
  "timestamp": "2026-09-20T20:00:00Z",
  "executeAt": "2026-10-16T00:40:00.000Z",
  "scheduledTime": "2026-10-15T18:40:00"
}
CampoTipoDescripción
messageIdstringID del mensaje creado. En envíos programados, úsalo para consultar, reprogramar o cancelar el recurso ; no necesitas campaignId ni runId
kindenumtemplate en las respuestas HTTP 202 de este endpoint
statusenumsent, delayed o scheduled
timestampstringFecha/hora en que se procesó la solicitud (ISO 8601 UTC)
executeAtstringFecha/hora en que se enviará el mensaje (ISO 8601 UTC). Solo presente en envíos diferidos o programados
delayMsnumberRetraso configurado en milisegundos. Solo presente cuando se usó delay
scheduledTimestringValor original de scheduleTime enviado en la solicitud. Solo presente cuando se usó scheduleTime

Los envíos con delay o scheduleTime quedan aceptados, pero todavía no enviados. Consulta Mensajes Programados para conocer sus estados y reglas de ejecución.

Contacto bloqueado

Un contacto con status: \"blocked\" nunca recibe plantillas. La API responde:

{
  "code": 409,
  "error": "Conflict - The resource state conflicts with this request",
  "details": {
    "code": "CONTACT_BLOCKED",
    "clientId": "client_123",
    "status": "blocked"
  }
}

La comprobación también se repite al ejecutar mensajes diferidos o programados.

Reglas de WhatsApp

Plantillas obligatorias

Para iniciar una conversación debes usar una plantilla pre-aprobada. No puedes enviar mensajes de texto libre hasta que el cliente responda.

Ventana de 24 horas

Las conversaciones permanecen activas durante 24 horas desde el último mensaje del cliente.

Si el cliente NO responde:

  • Envías la plantilla
  • El cliente no responde
  • No puedes enviar más mensajes hasta que responda

Si el cliente SÍ responde:

  • Envías la plantilla
  • El cliente responde
  • Puedes enviar mensajes libremente durante 24 horas
  • La ventana se reinicia con cada mensaje del cliente

Limitaciones de entrega

WhatsApp puede bloquear mensajes por:

  • Restricciones del país del cliente
  • Números en experimentos de WhatsApp
  • Clientes que desactivaron notificaciones de marketing

Consultar estado

Verifica si tu mensaje fue entregado:

  1. Desde la bandeja de entrada de la plataforma
  2. Usando el endpoint Obtener Conversación