API de plantillas de WhatsApp
Las plantillas de mensajes de WhatsApp son mensajes preescritos que han sido aprobados para enviarse fuera de la ventana de conversación normal de 24 horas; por ejemplo, un mensaje de bienvenida, un recordatorio de cita o un aviso de reinteracción. Esta API le permite listar, crear, editar, enviar, verificar, eliminar y enviar plantillas mediante programación.
Todas las rutas a continuación son relativas a la URL base de la API:
https://api.youraiconnector.com/v1
Cada solicitud debe estar autenticada. Consulte Autenticación para conocer los cuatro métodos aceptados. Los ejemplos en esta página utilizan el encabezado X-API-Key (y una forma de parámetro de consulta para cURL).
Nota: Las plantillas funcionan a través del canal de la API de WhatsApp Business, por lo que esta parte de la API requiere tanto acceso a la API como un plan que incluya canales de WhatsApp. Sin ellos, las solicitudes serán rechazadas con un 403.
Trabajar con subcuentas (agencias)
Estados de aprobación
Debido a que los mensajes enviados fuera de una conversación abierta deben ser revisados primero por WhatsApp, cada plantilla conlleva un status de aprobación:
| Estado | Significado |
|---|---|
draft |
Creada o guardada pero aún no enviada para revisión. Todavía puede editarla. |
received |
Enviada y aceptada en la cola de revisión. |
pending |
En revisión. |
approved |
Autorizada para el envío. |
rejected |
Rechazada. El campo rejection_reason explica el motivo; corríjalo y envíelo de nuevo. |
Solo las plantillas draft y rejected pueden editarse o (re)enviarse. Una vez que una plantilla está approved, queda bloqueada; cree una nueva si necesita realizar cambios.
Aprobación automática: Algunos canales no requieren un paso de revisión externa. Las plantillas creadas o enviadas para una campaña en dicho canal se almacenan como
approvedinmediatamente, sin un ID de contenido (sid).
Plantillas en cuentas conectadas a Meta
Estos endpoints funcionan de la misma manera independientemente de la conexión de WhatsApp que utilice su cuenta, pero lo que sucede detrás de ellos es diferente:
- En una conexión de WhatsApp gestionada, las plantillas se registran con el proveedor de mensajería y
sides el ID de contenido del proveedor (HXXXXXXXX…). - En una cuenta cuyo número se ejecuta en su propia cuenta de WhatsApp Business (cualquiera de las opciones de conexión de Meta), las plantillas se crean y revisan en esa cuenta de WhatsApp Business y
sides el ID de plantilla propio de Meta: una cadena numérica como"3394843740694756".statussigue utilizando los valores de la tabla anterior yrejection_reasonsigue conteniendo la explicación de Meta.
Existen dos endpoints adicionales para esto: uno para consultar qué conexión está utilizando y otro para reconciliar su lista de plantillas con su cuenta de WhatsApp Business. Las plantillas que ya existen en la cuenta de WhatsApp Business se importan a su biblioteca mediante la sincronización, por lo que un GET /whatsapp-templates posterior las enumera como cualquier otra plantilla.
Comprobar en qué conexión se ejecutan las plantillas
GET /whatsapp-templates/provider
| Campo | Descripción |
|---|---|
provider |
twilio cuando las plantillas se registran con el proveedor de mensajería gestionado, meta cuando residen en su propia cuenta de WhatsApp Business. |
lane |
Qué conexión de Meta se está utilizando: meta_cloud_api (su propia aplicación de Meta) o meta_embedded (conectada a través de nuestra aplicación de Meta). null en una conexión gestionada. |
waba_id |
La cuenta de WhatsApp Business en la que se crean las plantillas, o null. |
templates_enabled |
false cuando la conexión con Meta aún no se ha completado (no hay una cuenta de WhatsApp Business o un token de acceso almacenado). La creación o el envío de plantillas fallará con un 400 hasta que se complete. |
cURL
curl "https://api.youraiconnector.com/v1/whatsapp-templates/provider?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/provider", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/whatsapp-templates/provider",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"provider": "meta",
"lane": "meta_cloud_api",
"waba_id": "2357661648036355",
"templates_enabled": true
}
Sincronizar plantillas desde Meta
Actualiza el estado de aprobación de cada plantilla que reside en su cuenta de WhatsApp Business e importa cualquier plantilla que exista allí pero que aún no esté en su biblioteca. Es seguro llamarlo tantas veces como desee. En una conexión gestionada no hay nada que sincronizar, por lo que la llamada no hace nada y simplemente informa cuántas plantillas tiene.
POST /whatsapp-templates/meta-sync
| Campo | Descripción |
|---|---|
imported |
Plantillas encontradas en la cuenta de WhatsApp Business que se agregaron a su biblioteca mediante esta llamada. |
updated |
Plantillas existentes cuyo estado o detalles cambiaron. |
total |
Plantillas en su biblioteca después de la sincronización. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"provider": "meta",
"imported": 2,
"updated": 5,
"total": 12
}
Comunicación directa con Meta (avanzado)
Si necesita algo que los endpoints anteriores no exponen (encabezados de plantilla, pies de página, botones o una plantilla completamente creada a mano), /v1/meta-templates envía su solicitud directamente a la API de plantillas de Meta, sin almacenar nada en su biblioteca de plantillas. Solo funciona en cuentas cuyo número se ejecuta en su propia cuenta de WhatsApp Business; en una conexión gestionada, cada llamada devuelve 400 solicitándole que conecte una aplicación de Meta primero.
| Endpoint | Qué hace |
|---|---|
GET /meta-templates |
Enumera las plantillas en su cuenta de WhatsApp Business con su estado más reciente. Agregue ?name= para filtrar por un nombre de plantilla exacto. Devuelve { "success": true, "templates": [...] }. |
POST /meta-templates |
Crea una plantilla y la envía para revisión de Meta en un solo paso. Requiere name, language y body (o una matriz components completa en lugar de body). Opcional: variables (matriz de cadenas), category (MARKETING, UTILITY o AUTHENTICATION), header, footer, buttons. Devuelve 201 con { "success": true, "template": {...} }. |
DELETE /meta-templates/{name} |
Elimina la plantilla por su nombre de Meta: todos sus idiomas. Agregue ?hsm_id= con el ID de plantilla de Meta para eliminar un solo idioma. Devuelve { "success": true, "name": "..." }. |
Una plantilla que Meta rechaza devuelve 400 con la explicación propia de Meta en error.
Listar plantillas
Devuelve todas las plantillas de su cuenta, con un resumen ligero de cada una.
GET /whatsapp-templates
cURL
curl "https://api.youraiconnector.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/whatsapp-templates",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"data": [
{
"id": "template_abc123",
"name": "welcome_message",
"status": "approved",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!"
},
{
"id": "template_def456",
"name": "appointment_reminder",
"status": "pending",
"language": "en",
"body": "Hi {{first_name}}, this is a reminder about your appointment."
}
]
}
Obtener una plantilla
Devuelve el detalle completo de una plantilla individual, incluyendo sus variables, estado y marcas de tiempo.
GET /whatsapp-templates/{templateId}
cURL
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"template": {
"id": "template_abc123",
"name": "welcome_message",
"body": "Hi {{first_name}}, thanks for reaching out!",
"language": "en",
"variables": ["first_name"],
"status": "approved",
"sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"type": "general",
"category": "marketing",
"rejection_reason": null,
"campaign_id": "campaign123",
"date_created": "2026-06-01T10:00:00.000Z",
"date_updated": "2026-06-02T08:30:00.000Z",
"submitted_at": "2026-06-01T10:05:00.000Z",
"approved_at": "2026-06-02T08:30:00.000Z"
}
}
Una plantilla que no existe en su cuenta devuelve 404 con { "success": false, "error": "Template not found" }.
Crear una plantilla
Crea una plantilla para el mensaje de apertura de una campaña y la envía para su aprobación en un solo paso.
POST /whatsapp-templates
| Campo | Obligatorio | Descripción |
|---|---|---|
campaign_id |
Sí | La campaña a la que pertenece la plantilla. |
name |
Sí | Un nombre para la plantilla. |
language |
Sí | Código de idioma, por ejemplo en, es, de, pt_BR, zh_CN. |
body |
Sí | El texto del mensaje, hasta 1024 caracteres. |
variables |
No | Lista ordenada de nombres de variables utilizados en el cuerpo. |
Los marcadores de posición de variables pueden escribirse como {{first_name}}, {first_name} o [first_name]; todos se normalizan a la forma de doble llave.
El resultado depende de los canales de la campaña:
- Campaña de WhatsApp Business API: el contenido se envía para revisión de WhatsApp. La respuesta contiene
campaign_status(receivedopending) y untemplate_sid. - Un canal sin paso de revisión externa: la plantilla se almacena y se aprueba automáticamente (
campaign_status: "approved",template_sid: null). - Sin canal de WhatsApp en la campaña: no se crea nada y
campaign_statusesnot_applicable.
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": "campaign123",
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"]
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
campaign_id: "campaign123",
name: "welcome_message",
language: "en",
body: "Hi {{first_name}}, thanks for reaching out!",
variables: ["first_name"],
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"campaign_id": "campaign123",
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"],
},
)
data = res.json()
Respuesta (enviada para revisión)
{
"success": true,
"campaign_status": "pending",
"template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Crear una plantilla independiente
Crea una plantilla en su biblioteca de plantillas sin vincularla al mensaje inicial de una campaña. Este es el paso de creación del ciclo de vida que sigue el resto de esta página: créela aquí, edítela, envíela para revisión, consulte su estado y elimínela cuando ya no la necesite.
POST /whatsapp-templates/docs
| Campo | Obligatorio | Descripción |
|---|---|---|
name |
Sí | Un nombre para la plantilla. |
language |
Sí | Código de idioma, por ejemplo en, es, de, pt_BR, zh_CN. |
body |
Sí | El texto del mensaje, hasta 1024 caracteres. |
variables |
No | Lista ordenada de nombres de variables utilizados en el cuerpo. |
status |
No | draft (predeterminado) la almacena sin enviarla; submitted la pone en cola para la revisión de WhatsApp de inmediato. |
type |
No | general (predeterminado) o smart_followup. |
category |
No | marketing, utility, authentication o authentication-international. |
campaign_id |
No | Vincula la plantilla a una de sus campañas. |
Plantillas de autenticación (código de un solo uso). WhatsApp no acepta plantillas de autenticación de texto libre: el cuerpo del mensaje está preestablecido por WhatsApp y la plantilla debe incluir un botón de “copiar código”. Cuando crea una plantilla con
category: "authentication", la enviamos con ese formato fijo por usted. Subodyse mantiene como la vista previa que se muestra en la aplicación, pero el texto que recibe su contacto es la redacción propia de WhatsApp (el código, un recordatorio de seguridad y una nota de caducidad de 10 minutos). Declare exactamente una variable, por ejemplo["code"], y pase el código cuando realice el envío (consulte el campovariablesen Enviar una plantilla a un contacto). El código debe tener menos de 15 caracteres.
¿Qué creación debo usar? Use esta cuando desee una plantilla que usted mismo pueda editar y enviar. Use
POST /whatsapp-templates(arriba) cuando desee establecer el mensaje inicial de una campaña; esa opción requierecampaign_idy escribe directamente en la campaña.
Una plantilla creada como submitted se envía para la revisión de WhatsApp en segundo plano, por lo que debe consultar el endpoint de estado para conocer el resultado en lugar de esperar que aparezca en la respuesta.
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/docs?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"],
"status": "draft",
"category": "marketing"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/docs", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "welcome_message",
language: "en",
body: "Hi {{first_name}}, thanks for reaching out!",
variables: ["first_name"],
status: "draft",
category: "marketing",
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/docs",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"],
"status": "draft",
"category": "marketing",
},
)
data = res.json()
Respuesta
{
"success": true,
"template_id": "template_abc123",
"status": "draft"
}
Si falta un name, language o body, si el idioma no es compatible, si un status es distinto de draft o submitted, si un type o category es desconocido, o si el cuerpo supera los 1024 caracteres, se devolverá un 400 con un error explicativo. Un campaign_id que no sea una de sus campañas devolverá un 404.
Actualizar una plantilla
Edita una plantilla que aún no ha sido aprobada. Solo se pueden editar las plantillas con estado draft o rejected. Proporcione cualquier combinación de name, body, language y variables; solo se cambiarán los campos que envíe.
PUT /whatsapp-templates/{templateId}
La edición no vuelve a enviar la plantilla para su revisión. Utilice el endpoint de envío después.
cURL
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi {{first_name}}, here is an update for you.",
"variables": ["first_name"]
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
{
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
body: "Hi {{first_name}}, here is an update for you.",
variables: ["first_name"],
}),
}
);
const data = await res.json();
Python
import requests
res = requests.put(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"body": "Hi {{first_name}}, here is an update for you.",
"variables": ["first_name"],
},
)
data = res.json()
Respuesta
{
"success": true,
"template_id": "template_abc123"
}
Intentar editar una plantilla que ya está approved (o que no es editable por otro motivo), no enviar campos o enviar un valor no válido devuelve 400 con un error explicativo.
Enviar una plantilla para su aprobación
Envía una plantilla draft o rejected para su revisión. Las plantillas en un canal que no requiere revisión externa se aprueban de inmediato; todas las demás se envían a WhatsApp y el status devuelto (normalmente received o pending) se almacena en la plantilla.
POST /whatsapp-templates/{templateId}/submit
Las plantillas de seguimiento deben declarar y utilizar sus variables obligatorias antes de poder enviarse: un marcador de posición para el nombre y un marcador de posición de contexto personal para seguimientos inteligentes.
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
{ method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"template_id": "template_abc123",
"status": "pending",
"sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Comprobar el estado de aprobación
Un endpoint ligero para consultar el estado actual de una plantilla. El estado se lee del registro almacenado, que se actualiza periódicamente en segundo plano, por lo que una aprobación o rechazo muy reciente puede tardar un poco en aparecer.
GET /whatsapp-templates/{templateId}/status
cURL
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"template_id": "template_abc123",
"name": "welcome_message",
"status": "approved",
"sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"rejection_reason": null,
"date_updated": "2026-06-02T08:30:00.000Z"
}
Eliminar una plantilla
Elimina el registro de la plantilla de su cuenta.
DELETE /whatsapp-templates/{templateId}
Importante: En una conexión gestionada, solo se elimina el registro almacenado; el contenido que WhatsApp ya haya aprobado puede permanecer registrado en el proveedor de mensajería. En una cuenta que funciona con su propia cuenta de WhatsApp Business, la plantilla también se elimina de dicha cuenta. De cualquier modo, si una campaña sigue utilizando esta plantilla, redirija esa campaña a otra plantilla antes de eliminarla; de lo contrario, los envíos que dependan de ella fallarán.
cURL
curl -X DELETE "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
{ method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.delete(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"template_id": "template_abc123",
"note": "The template record was removed from your account. Content already approved by WhatsApp may remain registered with the messaging provider."
}
Enviar una plantilla a un contacto
Envía una plantilla aprobada a un contacto, incluso cuando no hay una conversación abierta; esto vuelve a abrir la sesión de chat. Puede dirigirse al contacto mediante contactId o mediante phoneNumber, y elegir la plantilla mediante whatsappTemplateId o mediante templateName.
POST /whatsapp-templates/send
| Campo | Obligatorio | Descripción |
|---|---|---|
contactId |
Uno de estos dos | El ID del contacto. |
phoneNumber |
Uno de estos dos | El número de teléfono del contacto (con código de país, sin espacios). Se busca o se crea si es necesario. |
whatsappTemplateId |
Uno de estos dos | El ID de la plantilla. |
templateName |
Uno de estos dos | El nombre de la plantilla, tal como se muestra en la aplicación. |
firstName |
No | Se utiliza para completar un contacto recién creado. |
lastName |
No | Se utiliza para completar un contacto recién creado. |
email |
No | Se utiliza para completar un contacto recién creado. |
variables |
No | Valores explícitos para las variables de la plantilla, organizados por nombre de variable, por ejemplo { "code": "482913" }. Un valor proporcionado aquí prevalece sobre los campos del contacto para esa variable; las variables que omita se seguirán completando a partir del contacto como se describe a continuación. Así es como se pasa un código de un solo uso a una plantilla de autenticación. |
El cuerpo de la plantilla admite la sustitución avanzada de variables:
- Variables básicas:
{{first_name}},{{email}},{{company}} - Valores predeterminados:
{{first_name|there}}muestratheresi el campo está vacío - Transformaciones:
{{company|uppercase}},{{name|lowercase}},{{name|capitalize}} - Combinado:
{{company|Your Company|uppercase}}
Créditos: El envío de una plantilla consume créditos. El costo exacto depende del país del destinatario y de la categoría de la plantilla.
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contactId": "contact123",
"whatsappTemplateId": "template_abc123"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/send", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
contactId: "contact123",
whatsappTemplateId: "template_abc123",
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/send",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"contactId": "contact123",
"whatsappTemplateId": "template_abc123",
},
)
data = res.json()
Respuesta
{
"success": true,
"data": "WhatsApp template message sent successfully"
}
Una solicitud a la que le falten tanto un identificador de contacto como ambos identificadores de plantilla devuelve 400. Si a su cuenta le faltan las credenciales de mensajería necesarias para enviar, la respuesta es 403.
Crear o actualizar la plantilla activa de una campaña
Un segundo par de endpoints para la plantilla de apertura de una campaña, definidos por ruta en lugar de por un campaign_id en el cuerpo. Estos son los que se deben usar para una campaña que ya está activa: a diferencia de Crear una plantilla arriba, la actualización aquí también vuelve a enviar los borradores de seguimiento de la campaña para su revisión, de modo que la plantilla de apertura y sus seguimientos permanezcan sincronizados.
POST /whatsapp-templates/campaign/{campaignId} crea la plantilla de apertura de la campaña. PUT /whatsapp-templates/campaign/{campaignId} la edita; la campaña debe tener ya una plantilla, o esto devolverá 400.
| Campo | Obligatorio | Descripción |
|---|---|---|
name |
Sí | Un nombre para la plantilla. |
language |
Sí | Código de idioma, por ejemplo en, es, de, pt_BR, zh_CN. |
body |
Sí | El texto del mensaje, hasta 1024 caracteres. |
variables |
Sí | Lista ordenada de nombres de variables utilizados en el cuerpo. Pase una matriz vacía si la plantilla no utiliza ninguno. |
cURL (crear)
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"]
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "welcome_message",
language: "en",
body: "Hi {{first_name}}, thanks for reaching out!",
variables: ["first_name"],
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"name": "welcome_message",
"language": "en",
"body": "Hi {{first_name}}, thanks for reaching out!",
"variables": ["first_name"],
},
)
data = res.json()
Respuesta
{
"success": true,
"campaign_status": "pending",
"template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"message": "WhatsApp template created and campaign updated successfully."
}
Para editar, cambie el método a PUT y utilice los mismos campos; esto vuelve a enviar la plantilla de apertura (y los borradores de seguimiento de la campaña, en una campaña de la API de WhatsApp) para su revisión.
Una campaña que no pertenece a su cuenta devuelve 404; una campaña que pertenece a otra cuenta para la que no está autorizado devuelve 403. Editar una campaña sin una plantilla existente devuelve 400.
Enviar una plantilla a un contacto existente
Una alternativa más sencilla, definida por ruta, a Enviar una plantilla a un contacto arriba: tanto la plantilla como el contacto deben existir ya; no se busca nada por nombre ni se crea sobre la marcha.
POST /whatsapp-templates/{templateId}/send-to-contact
| Campo | Obligatorio | Descripción |
|---|---|---|
contactId |
Sí | El ID del contacto. Debe pertenecer a su cuenta. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactId": "contact123" }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ contactId: "contact123" }),
}
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"contactId": "contact123"},
)
data = res.json()
Respuesta
{
"success": true,
"data": "WhatsApp template message sent successfully"
}
Créditos: El envío consume créditos, con el mismo precio que el endpoint anterior. Un
contactIdque falte o no esté en su cuenta devuelve403; untemplateIdque no exista devuelve404.
Envío masivo de una plantilla
Envíe una plantilla a muchos contactos en una sola llamada, con una vista previa del costo que puede mostrar antes de confirmar.
Estimar el costo primero
Devuelve el coste del envío, desglosado por país de destino, sin enviar nada ni descontar créditos. El precio de la plantilla es por país de destino, por lo que debe calcularse en el servidor con los contactos reales en lugar de estimarse en el cliente.
POST /whatsapp-templates/{templateId}/estimate-bulk-cost
| Campo | Obligatorio | Descripción |
|---|---|---|
contactIds |
Sí | Contactos a presupuestar, hasta 500 por llamada. Los duplicados se cuentan una sola vez. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactIds": ["contact123", "contact456"] }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
}
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
Respuesta
{
"success": true,
"data": {
"countries": [
{
"countryCode": "1",
"name": "United States",
"iso": "US",
"flag": "🇺🇸",
"contactCount": 120,
"costPerContact": 0.5,
"subtotal": 60.0
}
],
"totalContacts": 120,
"totalTemplateCost": 60.0,
"templateCategory": "marketing",
"skippedContacts": 2
}
}
skippedContacts cuenta los identificadores que faltaban, que no eran suyos o que no tenían número de teléfono; la estimación solo cubre el resto, por lo que un valor distinto de cero significa que el envío real llegará a menos contactos de los que seleccionó.
Enviar el lote
Envía la plantilla a todos los contactos de la lista, resolviendo cualquier variable inteligente por contacto y descontando créditos por envío.
POST /whatsapp-templates/{templateId}/bulk-send
| Campo | Obligatorio | Descripción |
|---|---|---|
contactIds |
Sí | Contactos a los que enviar, hasta 5000 por llamada. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactIds": ["contact123", "contact456"] }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
}
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
Respuesta
{
"success": true,
"data": { "sent": 118, "failed": 2, "total": 120 }
}
Un contacto que falla (no encontrado, no está en su cuenta o un error de envío) se omite y se cuenta en failed en lugar de detener el lote. Un contactIds vacío, más de 5000 identificadores en un envío (500 en una estimación) o un templateId faltante devuelve 400.
Reintentar un mensaje fallido
Dos endpoints para reenviar un mensaje que falló, sin crear un nuevo registro de mensaje ni gastar créditos nuevamente.
POST /whatsapp-templates/messages/{contactId}/{messageId}/retry-template reintenta específicamente un mensaje de plantilla fallido; vuelve a resolver el contenido de la plantilla desde la campaña si el mensaje fallido aún no lo contiene. Solo los mensajes con estado failed y tipo template pueden reintentarse de esta manera.
POST /whatsapp-templates/messages/{contactId}/{messageId}/retry es independiente del canal y funciona para cualquier mensaje fallido que no sea de plantilla (por ejemplo, WhatsApp Web), enviándolo a la ruta de envío correcta según el canal del mensaje. Acepta el estado failed, failed_connection, limit_exceeded o queued_retry.
Ninguno de los endpoints requiere un cuerpo de solicitud.
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
{ method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"data": "Message retry initiated successfully"
}
Para la versión independiente del canal, cambie la ruta a .../msg_abc789/retry. Un mensaje cuyo estado no sea elegible para reintento, o (en el endpoint de plantilla) que no sea un mensaje de plantilla, devuelve 400. Un contacto o mensaje faltante devuelve 404.
Perfil de WhatsApp Business
Administre el perfil de WhatsApp Business (información, dirección, descripción, correo electrónico, sitios web, categoría de negocio y logotipo) que se muestra a los contactos en WhatsApp. Funciona tanto en una conexión administrada como en una cuenta que ejecuta su propia cuenta de WhatsApp Business.
Guardar el perfil
PUT /whatsapp-templates/profile
| Campo | Obligatorio | Descripción |
|---|---|---|
phoneNumber |
Sí | El número de WhatsApp al que pertenece este perfil. Debe estar conectado a su cuenta. |
about |
No | Texto breve de “Información” que se muestra en el perfil. |
address |
No | Dirección del negocio. |
description |
No | Descripción más larga del negocio. |
email |
No | Correo electrónico de contacto que se muestra en el perfil. |
websites |
No | Matriz de URLs de sitios web. Cada una debe ser una URL válida. |
vertical |
No | Categoría del negocio, por ejemplo Retail o Professional Services. |
profilePictureHandle |
No | El identificador devuelto por el endpoint de carga de imágenes a continuación, para establecer la foto de perfil. |
cURL
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/profile?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+31612345678",
"about": "We reply within a few hours",
"email": "support@example.com",
"websites": ["https://example.com"]
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile", {
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
phoneNumber: "+31612345678",
about: "We reply within a few hours",
email: "support@example.com",
websites: ["https://example.com"],
}),
});
const data = await res.json();
Python
import requests
res = requests.put(
"https://api.youraiconnector.com/v1/whatsapp-templates/profile",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"phoneNumber": "+31612345678",
"about": "We reply within a few hours",
"email": "support@example.com",
"websites": ["https://example.com"],
},
)
data = res.json()
Respuesta
{
"success": true,
"data": "WhatsApp Business profile updated successfully"
}
Si falta un phoneNumber, una URL de sitio web no es válida o un phoneNumber no está conectado a su cuenta, se devolverá 400 o 404.
Cargar una foto de perfil
Descarga una imagen desde una URL que usted proporcione y la carga en WhatsApp, devolviendo un identificador. Pase ese identificador como profilePictureHandle en la llamada de guardar perfil anterior para establecerla como foto; este endpoint solo carga la imagen, no la establece por sí mismo.
POST /whatsapp-templates/profile/picture
| Campo | Obligatorio | Descripción |
|---|---|---|
phoneNumber |
Sí | El número de WhatsApp al que pertenece este perfil. |
fileUrl |
Sí | Una URL accesible públicamente de la imagen que se va a cargar. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+31612345678",
"fileUrl": "https://example.com/logo.png"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
phoneNumber: "+31612345678",
fileUrl: "https://example.com/logo.png",
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"phoneNumber": "+31612345678",
"fileUrl": "https://example.com/logo.png",
},
)
data = res.json()
Respuesta
{
"success": true,
"data": "1234567890123456"
}
data es el identificador de la imagen cargada. Si falta un phoneNumber o fileUrl, o un phoneNumber sin token de acceso de WhatsApp en el archivo, se devolverá 400; una fileUrl inaccesible o no válida devolverá un error que describe por qué falló la descarga.
Comprobar el estado de un remitente
Consulta (y actualiza) el estado de envío en tiempo real de un número de WhatsApp conectado con el proveedor de mensajería. Es útil para confirmar que un número realmente puede enviar mensajes antes de depender de él.
GET /whatsapp-templates/sender-status/{phoneNumber}
cURL
curl "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
Respuesta
{
"success": true,
"data": "ONLINE"
}
data es uno de ONLINE (enviando normalmente), PENDING (aún en proceso de verificación) o DELETED (el proveedor ya no reconoce a este remitente; vuelva a conectar el número). Un phoneNumber sin información de negocio de WhatsApp en el archivo devolverá 404.
Generar plantillas de seguimiento con IA
La plataforma puede redactar por usted las plantillas de seguimiento de WhatsApp de una campaña (los recordatorios que se envían cuando una conversación se queda en silencio) a partir de las propias instrucciones y objetivos de la campaña. Existe un endpoint de trabajo que se ejecuta en segundo plano, además de tres endpoints antiguos que se mantienen para integraciones existentes. Todos ellos consumen créditos de IA.
Iniciar un trabajo de generación
POST /campaigns/{campaignId}/template-generation
| Campo | Obligatorio | Descripción |
|---|---|---|
type |
No | all (el valor predeterminado) redacta todo el conjunto de seguimiento. cold_only redacta solo los mensajes para los contactos que nunca respondieron. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "all" }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ type: "all" }),
}
);
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"type": "all"},
)
data = res.json()
Respuesta (202)
{ "success": true, "campaign_id": "campaign_abc123", "type": "all" }
La llamada devuelve una respuesta tan pronto como el trabajo se pone en cola. Lea la campaña (GET /campaigns/{campaignId}, consulte la API de campañas) y observe su objeto template_generation_status hasta que finalice:
| Campo | Descripción |
|---|---|
status |
processing mientras se ejecuta el trabajo, luego completed o failed. |
progress |
De 0 a 100. |
current_template, total_templates |
Cuántas plantillas se han redactado hasta el momento, del total que redactará el trabajo: 11 para una campaña saliente o combinada, 9 en caso contrario. |
error |
Por qué se detuvo un trabajo failed, por ejemplo, por falta de créditos. |
started_at, completed_at |
Cuándo comenzó y terminó el trabajo. |
Las plantillas generadas se guardan en la campaña como cualquier otra, por lo que aparecen en Listar plantillas y deben pasar por la aprobación de WhatsApp antes de poder enviarse. Un 400 significa que type era algo distinto a all o cold_only; un 404 significa que la campaña no existe o pertenece a otra cuenta.
Los agentes tienen una versión gemela de esta llamada, POST /agents/{agentId}/template-generation, que redacta los seguimientos para un agente y finaliza durante la llamada en el caso habitual; consulte Generar mensajes de seguimiento en la API de agentes de IA.
Los endpoints de generación antiguos
Tres endpoints anteriores realizan el mismo trabajo y se mantienen para que las integraciones existentes sigan funcionando. El código nuevo debe utilizar el endpoint de trabajo anterior.
| Endpoint | Qué hace |
|---|---|
POST /whatsapp-templates/campaign/{campaignId}/generate-async |
Inicia la generación de seguimiento para la campaña en segundo plano y devuelve 202 con { "success": true, "data": { "result": "success", "message": "..." } }. Los créditos se cobran por adelantado (se omite en una cuenta que aporta su propia clave de IA) y el template_generation_status de la campaña informa del progreso exactamente como se indicó anteriormente. |
POST /whatsapp-templates/campaign/{campaignId}/generate-followups |
Genera las nueve plantillas de seguimiento durante la llamada (para una campaña creada antes de que existieran los seguimientos automáticos, o una que necesite que se redacten de nuevo) y devuelve 200 con templatesGenerated dentro de data. |
POST /whatsapp-templates/agent/{agentId}/generate-followups |
La misma generación síncrona dirigida por el agente. La respuesta añade agent_id, campaign_id y target: "campaign" cuando las plantillas se redactaron en la campaña del agente, "agent" (con campaign_id: null) cuando el agente no tiene campaña y se almacenaron en el propio agente. Un agente inexistente o ajeno es un 404. |
Los tres requieren seguimientos automáticos en la cuenta y suficientes créditos (un 400 indica cuál falta), y el par dirigido a la campaña devuelve 403 cuando la campaña pertenece a otra cuenta.
Errores de la API de plantillas
Los endpoints de plantillas devuelven el sobre de error estándar:
{
"success": false,
"error": "Template not found"
}
Un 404 en estos endpoints generalmente significa que el recurso no se encontró; ya sea porque no existe o porque pertenece a otra cuenta. Algunos endpoints (los de creación/actualización con ámbito de campaña y los envíos a un contacto existente) devuelven 403 en su lugar cuando la campaña o el contacto pertenecen a otra persona en lugar de no existir en absoluto. Algunos endpoints también incluyen un campo error_code que refleja el estado HTTP. Los códigos compartidos que puede devolver cualquier endpoint — 400, 401, 403 (su plan no incluye acceso a la API), 429 (límite de tasa) y 500 — se enumeran con orientación sobre reintentos en Errores y paginación.
Próximos pasos
- Autenticación — las cuatro formas de autenticar una solicitud.
- Errores y límites de tasa — códigos de estado y el límite de 300 solicitudes/min.
- API de campañas — gestione las campañas a las que están adjuntas las plantillas.