Enviar Mensaje Personalizado
Envía un mensaje a un cliente dentro de una conversación que ya está abierta. A diferencia de Enviar Plantilla — que sirve para iniciar la conversación — este endpoint asume que el cliente ya inició una conversación o respondió recientemente a una plantilla, por lo que la ventana de servicio sigue activa.
POST https://api.platica.mx/v1/messages Antes de enviar, verifica que la conversación esté dentro de la ventana de servicio. Consulta Obtener Conversación y asegúrate de que canSendDirectMessage sea true. Si está cerrada, primero usa Enviar Plantilla para reabrirla.
Disponible para WhatsApp, Instagram y Facebook. La compatibilidad por tipo de mensaje varía según el canal — consulta la sección Tipos de mensaje .
Cuerpo de la solicitud
{
"channelId": "521234567890",
"conversationId": "521234567890",
"content": "¡Hola! ¿En qué puedo ayudarte?",
"client": {
"name": "José",
"customFields": {
"placas": "ABC123"
}
}
} Parámetros del cuerpo
| Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
channelId | string | ID interno del canal O número de teléfono del agente (formato E.164 sin +) | ✓ |
conversationId | string | Número de teléfono del cliente en formato E.164 sin + | ✓ |
content | string | object | Contenido del mensaje. Si es string, se envía como texto. Para media e interactivos, usa un objeto — ver Tipos de mensaje | ✓ |
type | enum | text, image, video, file, audio, interactive, email. Opcional cuando content es string | — |
client | object | Información del cliente a actualizar (Upsert) | — |
campaignId | string | ID de la campaña a la que se atribuye el mensaje. Si se omite, se registra bajo la campaña api | — |
delay | number | Retraso en milisegundos (3,000 – 86,400,000) | — |
scheduleTime | string | Fecha/hora de envío programado (ISO 8601). Máximo 1 año en el futuro | — |
Si se envía el objeto client, se actualizará la información del perfil (o se creará si no existe), permitiendo al agente de IA tener acceso inmediato a los nuevos datos.
Tipos de mensaje
content puede ser un texto simple o un objeto estructurado. Cuando es objeto, debes especificar type y la forma de content depende del tipo.
Texto
Forma corta:
{
"channelId": "521234567890",
"conversationId": "521234567890",
"content": "¡Hola! ¿En qué puedo ayudarte?"
} Forma explícita:
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "text",
"content": { "text": "¡Hola! ¿En qué puedo ayudarte?" }
} Imagen
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "image",
"content": {
"image": {
"url": "https://cdn.assets.com/foto.jpg",
"caption": "Aquí está la foto que me pediste"
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.image.url | string | URL pública https:// de la imagen | ✓ |
content.image.caption | string | Texto que aparece debajo de la imagen | — |
Video
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "video",
"content": {
"video": {
"url": "https://cdn.assets.com/video.mp4",
"caption": "Mira este video"
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.video.url | string | URL pública https:// del video | ✓ |
content.video.caption | string | Texto que aparece debajo del video | — |
Documento / archivo
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "file",
"content": {
"file": {
"url": "https://cdn.assets.com/factura.pdf",
"filename": "factura-2025-09.pdf",
"caption": "Tu factura del mes"
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.file.url | string | URL pública https:// del archivo | ✓ |
content.file.filename | string | Nombre con el que el cliente verá el archivo | — |
content.file.caption | string | Texto que aparece junto al archivo | — |
Audio
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "audio",
"content": {
"audio": {
"url": "https://cdn.assets.com/nota.ogg"
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.audio.url | string | URL pública https:// del audio | ✓ |
Mensajes interactivos
Los mensajes interactivos (botones, listas y flows) están disponibles únicamente en WhatsApp.
Hasta 3 botones por mensaje. El cliente toca uno y la API recibe la respuesta como un mensaje normal con el id del botón seleccionado.
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "interactive",
"content": {
"type": "button",
"body": { "text": "¿Quieres confirmar tu cita?" },
"action": {
"buttons": [
{ "id": "confirmar", "title": "Sí, confirmar" },
{ "id": "reagendar", "title": "Reagendar" },
{ "id": "cancelar", "title": "Cancelar" }
]
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.body.text | string | Texto principal del mensaje | ✓ |
content.header | object | Encabezado opcional ({ type: "text", text }) | — |
content.footer.text | string | Texto pequeño debajo de los botones | — |
content.action.buttons[].id | string | Identificador del botón. Lo recibirás cuando el cliente lo toque | ✓ |
content.action.buttons[].title | string | Texto visible del botón (máx. 20 caracteres recomendado) | ✓ |
Hasta 10 filas en total, distribuidas en una o más secciones. El cliente abre la lista, toca una fila y la API recibe la respuesta con el id de la fila seleccionada.
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "interactive",
"content": {
"type": "list",
"body": { "text": "Elige el horario que prefieras" },
"action": {
"button": "Ver horarios",
"sections": [
{
"title": "Esta semana",
"rows": [
{ "id": "lun-10", "title": "Lunes 10:00", "description": "Disponible" },
{ "id": "mar-12", "title": "Martes 12:00", "description": "Disponible" }
]
}
]
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.body.text | string | Texto principal del mensaje | ✓ |
content.action.button | string | Texto del botón que abre la lista | ✓ |
content.action.sections[].title | string | Título de la sección | — |
content.action.sections[].rows[].id | string | Identificador de la fila. Lo recibirás cuando el cliente la toque | ✓ |
content.action.sections[].rows[].title | string | Texto visible de la fila | ✓ |
content.action.sections[].rows[].description | string | Texto secundario debajo del título | — |
Para enviar un Flow de WhatsApp ya publicado, indica flow_id (o flow_name) y el texto del CTA. La API genera automáticamente el flow_token y correlaciona la respuesta del cliente con el envío.
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "interactive",
"content": {
"type": "flow",
"body": { "text": "Completa tu registro en menos de un minuto" },
"action": {
"parameters": {
"flow_id": "1234567890",
"flow_cta": "Empezar"
}
}
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.body.text | string | Texto principal del mensaje | ✓ |
content.action.parameters.flow_id | string | ID del Flow publicado en WhatsApp. Alternativa: flow_name | ✓¹ |
content.action.parameters.flow_name | string | Nombre del Flow publicado. Alternativa a flow_id | ✓¹ |
content.action.parameters.flow_cta | string | Texto del botón que abre el Flow | ✓ |
¹ Debes enviar flow_id o flow_name, no es necesario ambos.
Instrucción al agente
Una instrucción no se envía al cliente: actúa sobre el agente que opera la conversación. Es útil cuando estás supervisando el chat desde la API y quieres que el agente espere o retome el control. El campo mode define el comportamiento.
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "instruction",
"content": {
"text": "Espera a que el cliente confirme la cita antes de continuar.",
"mode": "wait"
}
} | Campo | Tipo | Descripción | Requerido |
|---|---|---|---|
content.text | string | Orden o contexto que el agente debe tener en cuenta | ✓ |
content.mode | enum | wait o resume | ✓ |
Comportamiento por modo
wait: registra la instrucción como mensaje de sistema en el historial y deja la conversación esperando al próximo mensaje del cliente. El agente no responde de inmediato; cuando entre el siguiente mensaje del cliente, leerá la instrucción como contexto.resume: marca la conversación como reanudada y dispara al agente para que continúe el flujo usando la instrucción como guía. El agente puede decidir responder al cliente o no según su propia lógica.
{
"channelId": "521234567890",
"conversationId": "521234567890",
"type": "instruction",
"content": {
"text": "Continúa con el flujo de venta y ofrece un descuento del 10%.",
"mode": "resume"
}
} Las instrucciones también soportan delay y scheduleTime. Una instrucción programada se ejecuta en el momento configurado, no antes. Por ejemplo, podés agendar un resume con un mensaje de seguimiento para mañana a las 9:00.
Programación
Igual que en Enviar Plantilla , puedes enviar el mensaje inmediatamente, con un retraso, o en una fecha específica.
Envío con retraso (delay):
- Mínimo:
3000ms (3 segundos) - Máximo:
86400000ms (24 horas) - Ejemplo:
"delay": 5000envía el mensaje en 5 segundos
Envío programado (scheduleTime):
- Formato ISO 8601
- Debe ser una fecha futura
- No puede ser más de 1 año en el futuro
- Ejemplos:
"2025-07-01T18:40:00"— Hora de México (UTC-6)"2025-07-01T18:40:00Z"— Hora UTC"2025-07-01T18:40:00-06:00"— Con zona horaria específica
No puedes usar delay y scheduleTime en la misma solicitud.
La ventana de servicio se valida en el momento del envío real, no al programar. Si programas un mensaje y la ventana se cierra antes de que se ejecute, el envío fallará.
| Campo | Tipo | Descripción |
|---|---|---|
client.name | string | Nombre completo del cliente |
client.firstname | string | Primer nombre |
client.lastname | string | Apellido |
client.email | string | Correo electrónico |
client.birthdate | string | Fecha de nacimiento (dd/mm/yyyy) |
client.gender | enum | Género: male o female |
client.company | string | Nombre de la compañía |
client.country | enum | Código ISO 3166-1 alpha-2 (ej: MX, US) |
client.state | string | Estado de residencia |
client.city | string | Ciudad de residencia |
client.address | string | Dirección completa |
client.postalCode | string | Código postal |
client.customFields | map | Objeto con pares clave-valor de los campos personalizados definidos en el workspace. Consulta Campos Personalizados para ver los disponibles. |
client.owners | array | Correos de usuarios responsables |
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": "2025-02-14T12:00:00Z"
} Con delay:
{
"messageId": "msg_123xyz",
"status": "delayed",
"timestamp": "2025-02-14T12:00:00Z",
"executeAt": "2025-02-14T12:00:05.000Z",
"delayMs": 5000
} Con scheduleTime:
{
"messageId": "msg_123xyz",
"status": "scheduled",
"timestamp": "2025-02-14T12:00:00Z",
"executeAt": "2025-07-01T00:40:00.000Z",
"scheduledTime": "2025-07-01T18:40:00"
} | Campo | Tipo | Descripción |
|---|---|---|
messageId | string | ID del mensaje creado. Úsalo para rastrear el estado en la campaña |
status | enum | sent, delayed o scheduled |
timestamp | string | Fecha/hora en que se procesó la solicitud (ISO 8601 UTC) |
executeAt | string | Fecha/hora en que se enviará el mensaje (ISO 8601 UTC). Solo presente en envíos diferidos o programados |
delayMs | number | Retraso configurado en milisegundos. Solo presente cuando se usó delay |
scheduledTime | string | Valor original de scheduleTime enviado en la solicitud. Solo presente cuando se usó scheduleTime |
Errores comunes
| Código | Caso |
|---|---|
400 | Schema inválido, delay fuera del rango permitido, delay y scheduleTime enviados juntos, o scheduleTime inválido |
404 | No se encontró un agente para el channelId indicado, o el cliente no tiene una conversación abierta en ese canal |
422 | La conversación existe pero la ventana de servicio está cerrada. Envía una plantilla con Enviar Plantilla para reabrirla |
Reglas por canal
- Plantillas obligatorias para iniciar conversación. Una vez que el cliente responde, la ventana de servicio queda abierta 24 horas y puedes enviar cualquier tipo de mensaje hasta que se cierre.
- Cada mensaje del cliente reinicia la ventana.
- Soporta texto, imágenes, videos, archivos, audio, botones, listas y flows.
Instagram y Facebook
- Soporta texto, imágenes, videos, archivos y audio. Los mensajes interactivos (botones, listas, flows) no están disponibles fuera de WhatsApp.
- Las plataformas pueden tener ventanas y políticas distintas a las de WhatsApp; valida siempre
canSendDirectMessageantes de enviar.
Consultar estado
Verifica si tu mensaje fue entregado:
- Desde la bandeja de entrada de la plataforma.
- Usando el endpoint Obtener Conversación .