Trabajaremos con una key en la variable
KEY y el canal de WhatsApp con channelId/integrationId = 9. Sustituye por los tuyos. Todas las llamadas usan la URL base https://api-v2.sofiachat.com/api/v1.1 · Crea la key y verifica el acceso
Crea una API key con scopesread y write desde el panel (Configuración → API) y confirma que responde y que tu plan incluye campañas con GET /v1/me:
plan.limits.conversations y plan.usage.conversations (margen disponible) y que apiKey.scopes incluya write. Si Outbound no está en tu plan, las llamadas siguientes responden 403 PLAN_FEATURE_REQUIRED.
2 · Consigue una plantilla aprobada
Una campaña envía una plantilla aprobada. Lista las del canal conGET /v1/templates:
data viene vacío, créala con POST /v1/templates y envíala a revisión de Meta. Usa placeholders con nombre en el cuerpo:
POST /v1/templates/sync para traer el estado actualizado y repite el GET hasta ver status: "approved":
id de la plantilla aprobada (lo usaremos como templateId).
3 · Define los campos personalizados
Las variables de la plantilla que no son datos estándar del contacto viven encustom_fields. Declara su clave antes de importar contactos con POST /v1/contact-fields:
4 · Carga los contactos
Crea contactos uno a uno conPOST /v1/contacts y sus custom_fields…
POST /v1/contacts/import (mismas columnas que la plantilla de importación del panel):
id de los contactos creados.
5 · Crea el grupo y añade los contactos
El grupo es la audiencia reutilizable de la campaña. Créalo conPOST /v1/contact-groups y llénalo con POST /v1/contact-groups/:id/contacts:
6 · Crea la campaña y mapea cada variable
Crea la campaña conPOST /v1/campaigns. Sin scheduledAt, queda en draft (buen momento para revisar antes de enviar):
"Hola {{nombre}}, tu {{producto}} vence el {{fecha}}.". El arreglo parameterMapping.body se lee en orden, un elemento por variable:
Cada variable admite tres orígenes:
contact_field con field (first_name, last_name, email, phone, full_name), custom_field con key, o static con value (mismo texto para todos). Guarda el id de la campaña que devuelve la respuesta.
7 · Dispara el envío
Inícialo conPOST /v1/campaigns/:id/send:
sending y los mensajes salen de forma progresiva. (Si programaste scheduledAt, saldrá sola a esa hora; send la fuerza de inmediato.) Para detener una campaña en draft o scheduled, usa POST /v1/campaigns/:id/cancel.
8 · Sigue el avance y revisa los fallos
Consulta los contadores en el detalle de la campaña conGET /v1/campaigns/:id:
recipientCounts resume el estado: { total, pending, sending, sent, delivered, read, failed, skipped }. Cuando pending y sending llegan a 0, terminó. Lista los destinatarios que fallaron con GET /v1/campaigns/:id/recipients para depurar tus listas:
status, el wa_message_id y el error si lo hubo.
9 · Interpreta los fallos más comunes
Cuando un destinatario responde, se abre la ventana de 24 h y su conversación entra al panel bajo el
conversationTagId que definiste, para que la atienda la IA o un agente. Para automatizar este ciclo (renovaciones diarias, reintentos), mira las recetas de integración.
