wa-gateway API (1.0.0)

Download OpenAPI specification:

License: LicenseRef-Proprietary

Pasarela multi-tenant para WhatsApp Business (Meta Cloud API).

API única que usan todas las aplicaciones para enviar y recibir mensajes de WhatsApp, gestionar plantillas, atender conversaciones y consultar costes, sin hablar nunca con Meta.

Autenticación

Esquema Quién lo usa Cómo se obtiene
ApiKey El backend de una app, de servidor a servidor Clave wak_live_<prefijo>_<secreto> creada con la API de administración o en /v1/api-keys
EmbedSession La UI embebida en el navegador POST /v1/embed/tokens (backend) y después POST /v1/embed/session (iframe)
AdminToken Vuestro equipo, API /admin/v1 SSO corporativo; en desarrollo, un token estático

Con una clave de API fijada a un tenant, el tenant se deduce de la clave. Con una clave multi-tenant hay que enviar X-Tenant-Id o X-Tenant-Ref. Un recurso de otro tenant responde siempre 404.

En cada llamada el gateway comprueba, por este orden: clave válida y no revocada, tenant activo, app habilitada para el tenant, licencia vigente, función incluida en la licencia y alcance de la clave (x-required-scope de cada operación). El primer fallo corta la petición.

Convenciones

  • Identificadores con prefijo (ten_, msg_, cnv_...) seguido de 32 caracteres hexadecimales.
  • Fechas en ISO 8601 UTC. Teléfonos con o sin +; se normalizan a dígitos con prefijo de país.
  • Paginación por cursor: ?limit=50&cursor=... y respuesta { "data": [...], "next_cursor": "..." | null }.
  • Idempotencia: cabecera Idempotency-Key en cualquier POST; se conserva 24 horas.
  • Límite de peticiones por clave, con cabeceras X-RateLimit-*; al superarlo, 429 y Retry-After.
  • Todas las respuestas llevan X-Request-Id.
  • Versionado en la ruta. Dentro de /v1 solo hay cambios compatibles; las retiradas se anuncian con Deprecation y Sunset al menos 6 meses antes.

Envío asíncrono

POST /v1/messages responde 202 con el mensaje en estado queued. El estado final llega por los eventos whatsapp.message.status (ver la sección webhooks) o consultando GET /v1/messages/{id}.

Messages

Envío y consulta de mensajes.

Enviar un mensaje

Valida, encola y responde 202. Validaciones, en orden: formato del número, licencia y límite mensual, número de origen conectado y WABA sin bloqueo de pago, plantilla aprobada y variables correctas, ventana de 24 h abierta para tipos que no son plantilla, y consentimiento del contacto.

Authorizations:
ApiKey
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
to
required
string (PhoneInput) ^\+?[0-9 ()-]{7,20}$

Teléfono con o sin + y con espacios; se normaliza a dígitos con prefijo de país.

phone_number_id
string (NumberId) ^num_[0-9a-f]{32}$
object

Crea o actualiza el contacto en la misma llamada.

external_ref
string <= 200 characters

Referencia de negocio de vuestra app (nº de factura, cita...).

priority
string (MessagePriority)
Enum: "normal" "bulk"

bulk usa un carril aparte que no puede ocupar más del 50 % de la tasa del número.

type
required
string
Value: "text"
required
object (TextContent)

Responses

Request samples

Content type
application/json
Example
{
  • "to": "+34 600 111 222",
  • "type": "template",
  • "template": {
    },
  • "contact": {
    },
  • "external_ref": "cita-48213"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "contact_id": "string",
  • "number_id": "string",
  • "direction": "inbound",
  • "type": "text",
  • "status": "queued",
  • "to": "string",
  • "from": "string",
  • "body": "string",
  • "template_id": "string",
  • "media_id": "string",
  • "reply_to_message_id": "string",
  • "payload": { },
  • "reply": {
    },
  • "via": "api",
  • "wa_message_id": "string",
  • "external_ref": "string",
  • "origin_app_id": "string",
  • "sent_by_agent_id": "string",
  • "error": {
    },
  • "billable": true,
  • "pricing_category": "string",
  • "pricing_type": "string",
  • "queued_at": "2026-10-12T09:41:07Z",
  • "sent_at": "2026-10-12T09:41:07Z",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "read_at": "2026-10-12T09:41:07Z",
  • "failed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Listar mensajes

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

external_ref
string <= 200 characters
status
string (MessageStatus)
Enum: "queued" "sending" "sent" "delivered" "read" "failed" "received"
direction
string (MessageDirection)
Enum: "inbound" "outbound"
conversation_id
string (ConversationId) ^cnv_[0-9a-f]{32}$
from
string <date-time>
to
string <date-time>
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Consultar un mensaje

Estado, error y precio (billable, pricing_category) de un mensaje.

Authorizations:
ApiKeyEmbedSession
path Parameters
message_id
required
string (MessageId) ^msg_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "contact_id": "string",
  • "number_id": "string",
  • "direction": "inbound",
  • "type": "text",
  • "status": "queued",
  • "to": "string",
  • "from": "string",
  • "body": "string",
  • "template_id": "string",
  • "media_id": "string",
  • "reply_to_message_id": "string",
  • "payload": { },
  • "reply": {
    },
  • "via": "api",
  • "wa_message_id": "string",
  • "external_ref": "string",
  • "origin_app_id": "string",
  • "sent_by_agent_id": "string",
  • "error": {
    },
  • "billable": true,
  • "pricing_category": "string",
  • "pricing_type": "string",
  • "queued_at": "2026-10-12T09:41:07Z",
  • "sent_at": "2026-10-12T09:41:07Z",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "read_at": "2026-10-12T09:41:07Z",
  • "failed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Redactar un mensaje recibido

Borra el contenido de un mensaje recibido (texto, respuesta de botón o de formulario) para que un dato sensible, como un DNI, no se quede guardado. Sustituye el cuerpo por [dato redactado], vacía el payload y borra también las copias guardadas del evento y del aviso original de Meta. No recupera lo que ya se entregó a un receptor de eventos, ni lo que Meta o el móvil del cliente conserven. Repetirlo no cambia nada.

Authorizations:
ApiKeyEmbedSession
path Parameters
message_id
required
string (MessageId) ^msg_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "contact_id": "string",
  • "number_id": "string",
  • "direction": "inbound",
  • "type": "text",
  • "status": "queued",
  • "to": "string",
  • "from": "string",
  • "body": "string",
  • "template_id": "string",
  • "media_id": "string",
  • "reply_to_message_id": "string",
  • "payload": { },
  • "reply": {
    },
  • "via": "api",
  • "wa_message_id": "string",
  • "external_ref": "string",
  • "origin_app_id": "string",
  • "sent_by_agent_id": "string",
  • "error": {
    },
  • "billable": true,
  • "pricing_category": "string",
  • "pricing_type": "string",
  • "queued_at": "2026-10-12T09:41:07Z",
  • "sent_at": "2026-10-12T09:41:07Z",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "read_at": "2026-10-12T09:41:07Z",
  • "failed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Mostrar «escribiendo…» al cliente

Marca como leído un mensaje recibido y muestra al cliente el indicador de escritura, que dura hasta 25 segundos o hasta que se envía la respuesta. Úsalo cuando la respuesta vaya a tardar más de un segundo. Repetirlo lo renueva.

Authorizations:
ApiKeyEmbedSession
path Parameters
message_id
required
string (MessageId) ^msg_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Reintentar un envío fallido

Solo si el mensaje está en failed y el error es recuperable (error.retryable = true) o es outcome_unknown. Un reintento de outcome_unknown puede duplicar el mensaje en el móvil.

Authorizations:
ApiKeyEmbedSession
path Parameters
message_id
required
string (MessageId) ^msg_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "contact_id": "string",
  • "number_id": "string",
  • "direction": "inbound",
  • "type": "text",
  • "status": "queued",
  • "to": "string",
  • "from": "string",
  • "body": "string",
  • "template_id": "string",
  • "media_id": "string",
  • "reply_to_message_id": "string",
  • "payload": { },
  • "reply": {
    },
  • "via": "api",
  • "wa_message_id": "string",
  • "external_ref": "string",
  • "origin_app_id": "string",
  • "sent_by_agent_id": "string",
  • "error": {
    },
  • "billable": true,
  • "pricing_category": "string",
  • "pricing_type": "string",
  • "queued_at": "2026-10-12T09:41:07Z",
  • "sent_at": "2026-10-12T09:41:07Z",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "read_at": "2026-10-12T09:41:07Z",
  • "failed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Conversations

Bandeja de entrada del chat.

Listar conversaciones

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

status
string (ConversationStatus)
Enum: "open" "pending" "closed"
assigned_agent_id
string

Use none para las sin asignar.

unread
boolean
q
string <= 100 characters

Busca por nombre o teléfono.

external_ref
string
updated_since
string <date-time>
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Detalle de una conversación

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "number_id": "string",
  • "contact": {
    },
  • "status": "open",
  • "assigned_agent_id": "string",
  • "last_inbound_at": "2026-10-12T09:41:07Z",
  • "window_expires_at": "2026-10-12T09:41:07Z",
  • "window_open": true,
  • "last_message_at": "2026-10-12T09:41:07Z",
  • "last_message_preview": "string",
  • "unread_count": 0,
  • "external_ref": "string",
  • "tags": [
    ],
  • "closed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Cambiar estado, asignación o etiquetas

Asignar es atómico: si la conversación ya está asignada a otro agente responde 409 already_assigned. Un supervisor o admin puede reasignar.

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
non-empty
status
string (ConversationStatus)
Enum: "open" "pending" "closed"
AgentId (string) or null
tags
Array of strings <= 20 items [ items <= 50 characters ]

Responses

Request samples

Content type
application/json
Example
{
  • "assigned_agent_id": "agt_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "status": "open"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "number_id": "string",
  • "contact": {
    },
  • "status": "open",
  • "assigned_agent_id": "string",
  • "last_inbound_at": "2026-10-12T09:41:07Z",
  • "window_expires_at": "2026-10-12T09:41:07Z",
  • "window_open": true,
  • "last_message_at": "2026-10-12T09:41:07Z",
  • "last_message_preview": "string",
  • "unread_count": 0,
  • "external_ref": "string",
  • "tags": [
    ],
  • "closed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Mensajes del hilo

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Responder como agente

Mismo cuerpo que POST /v1/messages, sin to ni phone_number_id (salen de la conversación).

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
external_ref
string <= 200 characters
priority
string (MessagePriority)
Enum: "normal" "bulk"

bulk usa un carril aparte que no puede ocupar más del 50 % de la tasa del número.

type
required
string
Value: "text"
required
object (TextContent)

Responses

Request samples

Content type
application/json
Example
{
  • "external_ref": "string",
  • "priority": "normal",
  • "type": "text",
  • "text": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "contact_id": "string",
  • "number_id": "string",
  • "direction": "inbound",
  • "type": "text",
  • "status": "queued",
  • "to": "string",
  • "from": "string",
  • "body": "string",
  • "template_id": "string",
  • "media_id": "string",
  • "reply_to_message_id": "string",
  • "payload": { },
  • "reply": {
    },
  • "via": "api",
  • "wa_message_id": "string",
  • "external_ref": "string",
  • "origin_app_id": "string",
  • "sent_by_agent_id": "string",
  • "error": {
    },
  • "billable": true,
  • "pricing_category": "string",
  • "pricing_type": "string",
  • "queued_at": "2026-10-12T09:41:07Z",
  • "sent_at": "2026-10-12T09:41:07Z",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "read_at": "2026-10-12T09:41:07Z",
  • "failed_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Marcar como leída

Pone unread_count a 0 y marca como leído en Meta el último mensaje entrante.

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Notas internas

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Añadir una nota interna

Authorizations:
ApiKeyEmbedSession
path Parameters
conversation_id
required
string (ConversationId) ^cnv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
body
required
string [ 1 .. 4000 ] characters

Responses

Request samples

Content type
application/json
{
  • "body": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "conversation_id": "string",
  • "agent_id": "string",
  • "body": "string",
  • "created_at": "2026-10-12T09:41:07Z"
}

Contacts

Contactos finales y consentimiento.

Listar contactos

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

external_ref
string
q
string <= 100 characters

Busca por nombre o teléfono.

opt_in_status
string (OptInStatus)
Enum: "unknown" "opted_in" "opted_out"
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Crear un contacto

Si ya existe un contacto con ese wa_id, lo devuelve con 200 en lugar de crearlo.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
phone
required
string (PhoneInput) ^\+?[0-9 ()-]{7,20}$

Teléfono con o sin + y con espacios; se normaliza a dígitos con prefijo de país.

display_name
string <= 200 characters
external_ref
string <= 200 characters
locale
string <= 10 characters
object

Responses

Request samples

Content type
application/json
{
  • "phone": "+34 600 111 222",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "attributes": { }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "wa_id": "string",
  • "phone_e164": "string",
  • "profile_name": "string",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "opt_in_status": "unknown",
  • "opt_in_source": "string",
  • "opt_in_at": "2026-10-12T09:41:07Z",
  • "opt_out_at": "2026-10-12T09:41:07Z",
  • "attributes": { },
  • "blocked": true,
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Detalle de un contacto

Authorizations:
ApiKeyEmbedSession
path Parameters
contact_id
required
string (ContactId) ^ctc_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "wa_id": "string",
  • "phone_e164": "string",
  • "profile_name": "string",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "opt_in_status": "unknown",
  • "opt_in_source": "string",
  • "opt_in_at": "2026-10-12T09:41:07Z",
  • "opt_out_at": "2026-10-12T09:41:07Z",
  • "attributes": { },
  • "blocked": true,
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Editar un contacto

Authorizations:
ApiKeyEmbedSession
path Parameters
contact_id
required
string (ContactId) ^ctc_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
display_name
string <= 200 characters
external_ref
string <= 200 characters
locale
string <= 10 characters
object
blocked
boolean

Responses

Request samples

Content type
application/json
{
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "attributes": { },
  • "blocked": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "wa_id": "string",
  • "phone_e164": "string",
  • "profile_name": "string",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "opt_in_status": "unknown",
  • "opt_in_source": "string",
  • "opt_in_at": "2026-10-12T09:41:07Z",
  • "opt_out_at": "2026-10-12T09:41:07Z",
  • "attributes": { },
  • "blocked": true,
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Borrado RGPD de un contacto

Elimina el contacto, sus conversaciones, mensajes y medios, y anonimiza su rastro en audit_log. No se puede deshacer.

Authorizations:
ApiKeyEmbedSession
path Parameters
contact_id
required
string (ContactId) ^ctc_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Registrar consentimiento

Authorizations:
ApiKeyEmbedSession
path Parameters
contact_id
required
string (ContactId) ^ctc_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
source
required
string <= 100 characters

Origen del consentimiento (formulario_web, alta_en_tienda...).

at
string <date-time> (Timestamp)

Responses

Request samples

Content type
application/json
{
  • "source": "formulario_web",
  • "at": "2026-10-12T09:30:00Z"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "wa_id": "string",
  • "phone_e164": "string",
  • "profile_name": "string",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "opt_in_status": "unknown",
  • "opt_in_source": "string",
  • "opt_in_at": "2026-10-12T09:41:07Z",
  • "opt_out_at": "2026-10-12T09:41:07Z",
  • "attributes": { },
  • "blocked": true,
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Registrar la baja de un contacto

Authorizations:
ApiKeyEmbedSession
path Parameters
contact_id
required
string (ContactId) ^ctc_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
optional
reason
string <= 200 characters

Responses

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "wa_id": "string",
  • "phone_e164": "string",
  • "profile_name": "string",
  • "display_name": "string",
  • "external_ref": "string",
  • "locale": "string",
  • "opt_in_status": "unknown",
  • "opt_in_source": "string",
  • "opt_in_at": "2026-10-12T09:41:07Z",
  • "opt_out_at": "2026-10-12T09:41:07Z",
  • "attributes": { },
  • "blocked": true,
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Templates

Plantillas de mensaje y biblioteca compartida.

Listar plantillas

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

status
string (TemplateStatus)
Enum: "draft" "pending" "approved" "rejected" "paused" "disabled" "in_appeal" "deleted"
category
string (TemplateCategory)
Enum: "marketing" "utility" "authentication"
language
string
name
string
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Crear una plantilla

Se guarda como draft. Con submit: true se envía a revisión de Meta y queda en pending. El gateway convierte este formato al de componentes de Meta. Comprueba license.limits.max_templates y los topes de Meta (250 plantillas por WABA sin negocio verificado, 6.000 con él, 100 creaciones por hora).

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
number_id
string (NumberId) ^num_[0-9a-f]{32}$
name
required
string^[a-z0-9_]{1,512}$
language
required
string
category
required
string (TemplateCategory)
Enum: "marketing" "utility" "authentication"
parameter_format
string
Default: "positional"
Enum: "positional" "named"
object (TemplateHeader)
required
object (TemplateBodyInput)
footer
string <= 60 characters
Array of objects (TemplateButton) <= 10 items
submit
boolean
Default: false

Enviar a revisión de Meta nada más crearla.

Responses

Request samples

Content type
application/json
{
  • "name": "recordatorio_cita",
  • "language": "es",
  • "category": "utility",
  • "header": {
    },
  • "body": {
    },
  • "footer": "Responde a este mensaje si necesitas cambiarla",
  • "buttons": [
    ],
  • "submit": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "meta_template_id": "string",
  • "name": "string",
  • "language": "string",
  • "category": "marketing",
  • "parameter_format": "positional",
  • "status": "draft",
  • "quality_rating": "string",
  • "rejected_reason": "string",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "components": [
    ],
  • "variables": [
    ],
  • "revision": 1,
  • "origin": "gateway",
  • "library_code": "string",
  • "last_synced_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Resincronizar plantillas con Meta

Importa las creadas en WhatsApp Manager, corrige estados y marca como borradas las que ya no existen.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "job_id": "string",
  • "status": "queued"
}

Detalle de una plantilla

Authorizations:
ApiKeyEmbedSession
path Parameters
template_id
required
string (TemplateId) ^tpl_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "meta_template_id": "string",
  • "name": "string",
  • "language": "string",
  • "category": "marketing",
  • "parameter_format": "positional",
  • "status": "draft",
  • "quality_rating": "string",
  • "rejected_reason": "string",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "components": [
    ],
  • "variables": [
    ],
  • "revision": 1,
  • "origin": "gateway",
  • "library_code": "string",
  • "last_synced_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Editar una plantilla

Crea una revisión nueva (revision + 1) y, si estaba enviada, la devuelve a pending. Meta limita las ediciones por periodo.

Authorizations:
ApiKeyEmbedSession
path Parameters
template_id
required
string (TemplateId) ^tpl_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
non-empty
category
string (TemplateCategory)
Enum: "marketing" "utility" "authentication"
object (TemplateHeader)
object (TemplateBodyInput)
footer
string <= 60 characters
Array of objects (TemplateButton) <= 10 items
submit
boolean
Default: false

Responses

Request samples

Content type
application/json
{
  • "category": "marketing",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "submit": false
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "meta_template_id": "string",
  • "name": "string",
  • "language": "string",
  • "category": "marketing",
  • "parameter_format": "positional",
  • "status": "draft",
  • "quality_rating": "string",
  • "rejected_reason": "string",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "components": [
    ],
  • "variables": [
    ],
  • "revision": 1,
  • "origin": "gateway",
  • "library_code": "string",
  • "last_synced_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Borrar una plantilla

Borra en Meta solo la plantilla de ese idioma (se envía hsm_id) y la marca deleted.

Authorizations:
ApiKeyEmbedSession
path Parameters
template_id
required
string (TemplateId) ^tpl_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Enviar un borrador a revisión

Authorizations:
ApiKeyEmbedSession
path Parameters
template_id
required
string (TemplateId) ^tpl_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "meta_template_id": "string",
  • "name": "string",
  • "language": "string",
  • "category": "marketing",
  • "parameter_format": "positional",
  • "status": "draft",
  • "quality_rating": "string",
  • "rejected_reason": "string",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "components": [
    ],
  • "variables": [
    ],
  • "revision": 1,
  • "origin": "gateway",
  • "library_code": "string",
  • "last_synced_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Vista previa con variables

Devuelve el texto ya renderizado sin enviar nada.

Authorizations:
ApiKeyEmbedSession
path Parameters
template_id
required
string (TemplateId) ^tpl_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
required
Array of strings or object (TemplateVariables)

Responses

Request samples

Content type
application/json
{
  • "variables": [
    ]
}

Response samples

Content type
application/json
{
  • "header": "string",
  • "body": "string",
  • "footer": "string",
  • "buttons": [
    ]
}

Plantillas base disponibles

Biblioteca global mantenida por vosotros. No depende del tenant.

Authorizations:
ApiKeyEmbedSession
query Parameters
language
string
category
string (TemplateCategory)
Enum: "marketing" "utility" "authentication"
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Activar una plantilla de la biblioteca

Crea la plantilla en la WABA del tenant con el contenido de la biblioteca y la envía a revisión.

Authorizations:
ApiKeyEmbedSession
path Parameters
code
required
string^[a-z0-9_]{1,100}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "meta_template_id": "string",
  • "name": "string",
  • "language": "string",
  • "category": "marketing",
  • "parameter_format": "positional",
  • "status": "draft",
  • "quality_rating": "string",
  • "rejected_reason": "string",
  • "header": {
    },
  • "body": {
    },
  • "footer": "string",
  • "buttons": [
    ],
  • "components": [
    ],
  • "variables": [
    ],
  • "revision": 1,
  • "origin": "gateway",
  • "library_code": "string",
  • "last_synced_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Numbers

Cuenta de WhatsApp, números y alta con Embedded Signup.

Cuenta de WhatsApp del tenant

WABA, verificación del negocio, modo de facturación y estado de pago.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "waba_id": "string",
  • "business_id": "string",
  • "name": "string",
  • "currency": "string",
  • "timezone_id": "string",
  • "billing_mode": "meta_direct",
  • "payment_status": "awaiting_payment",
  • "business_verification_status": "string",
  • "account_review_status": "string",
  • "status": "active",
  • "subscribed_at": "2026-10-12T09:41:07Z"
}

Listar números

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Detalle de un número

Authorizations:
ApiKeyEmbedSession
path Parameters
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Marcar el número predeterminado

Authorizations:
ApiKeyEmbedSession
path Parameters
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
is_default
required
boolean
Value: true

Responses

Request samples

Content type
application/json
{
  • "is_default": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Desconectar un número

Deja de enviar y recibir por ese número. No lo elimina de la cuenta de Meta del cliente.

Authorizations:
ApiKeyEmbedSession
path Parameters
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Releer el estado del número en Meta

Authorizations:
ApiKeyEmbedSession
path Parameters
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Iniciar el alta de un número (Embedded Signup v4)

Devuelve state, config_id y app_id para abrir el Embedded Signup en una ventana propia del gateway. state es de un solo uso y caduca a los 30 minutos.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
billing_mode
string (BillingMode)
Enum: "meta_direct" "platform_credit_line"
onboarding_type
string
Default: "dedicated"
Enum: "dedicated" "business_app"

business_app conecta un número que ya usa la app WhatsApp Business sin quitárselo (coexistencia).

return_url
string <uri>

Responses

Request samples

Content type
application/json
{
  • "billing_mode": "meta_direct",
  • "onboarding_type": "dedicated",
  • "return_url": "http://example.com"
}

Response samples

Content type
application/json
{
  • "session_id": "string",
  • "state": "string",
  • "config_id": "string",
  • "app_id": "string",
  • "graph_version": "v25.0",
  • "onboarding_type": "dedicated",
  • "extras": { },
  • "expires_at": "2026-10-12T09:41:07Z"
}

Progreso del alta

Authorizations:
ApiKeyEmbedSession
path Parameters
session_id
required
string (SignupSessionId) ^sus_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "session_id": "string",
  • "step": "created",
  • "billing_mode": "meta_direct",
  • "onboarding_type": "dedicated",
  • "number_id": "string",
  • "payment_status": "awaiting_payment",
  • "error": { },
  • "expires_at": "2026-10-12T09:41:07Z",
  • "completed_at": "2026-10-12T09:41:07Z"
}

Cerrar el alta con el code de Meta

Idempotente por state: repetirla devuelve la sesión existente. El code vale 30 segundos; el gateway lo canjea, suscribe webhooks, registra el número y lee su estado en un worker.

Authorizations:
ApiKeyEmbedSession
path Parameters
session_id
required
string (SignupSessionId) ^sus_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
state
required
string
code
required
string

Código canjeable de Meta; vale 30 segundos.

waba_id
required
string
phone_number_id
string

Obligatorio en un alta dedicated. En coexistencia Meta puede no enviarlo: si se omite y la cuenta tiene un solo número, se usa ese.

business_id
string

Responses

Request samples

Content type
application/json
{
  • "state": "string",
  • "code": "string",
  • "waba_id": "string",
  • "phone_number_id": "string",
  • "business_id": "string"
}

Response samples

Content type
application/json
{
  • "session_id": "string",
  • "step": "created",
  • "billing_mode": "meta_direct",
  • "onboarding_type": "dedicated",
  • "number_id": "string",
  • "payment_status": "awaiting_payment",
  • "error": { },
  • "expires_at": "2026-10-12T09:41:07Z",
  • "completed_at": "2026-10-12T09:41:07Z"
}

Media

Archivos adjuntos.

Subir un archivo

Multipart. Valida tamaño y tipo, analiza el archivo y devuelve un med_... para usarlo en un mensaje.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: multipart/form-data
required
file
required
string <binary>
file_name
string <= 255 characters

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "mime_type": "string",
  • "size_bytes": 0,
  • "file_name": "string",
  • "sha256": "string",
  • "created_at": "2026-10-12T09:41:07Z"
}

Descargar un archivo

Redirige a una URL firmada de 5 minutos. Los tipos que no son imagen, audio o vídeo se sirven como adjunto.

Authorizations:
ApiKeyEmbedSession
path Parameters
media_id
required
string (MediaId) ^med_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Agents

Agentes del chat.

Listar agentes

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Crear un agente

Comprueba license.limits.max_agents. Los agentes también se crean solos la primera vez que entran por la UI embebida.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
external_user_id
required
string <= 200 characters
display_name
required
string <= 200 characters
email
string <email>
role
string (AgentRole)
Enum: "agent" "supervisor" "admin"

Responses

Request samples

Content type
application/json
{
  • "external_user_id": "string",
  • "display_name": "string",
  • "email": "user@example.com",
  • "role": "agent"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "external_user_id": "string",
  • "display_name": "string",
  • "email": "user@example.com",
  • "role": "agent",
  • "active": true,
  • "created_at": "2026-10-12T09:41:07Z"
}

Editar o desactivar un agente

Authorizations:
ApiKeyEmbedSession
path Parameters
agent_id
required
string (AgentId) ^agt_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
non-empty
display_name
string <= 200 characters
email
string <email>
role
string (AgentRole)
Enum: "agent" "supervisor" "admin"
active
boolean

Responses

Request samples

Content type
application/json
{
  • "display_name": "string",
  • "email": "user@example.com",
  • "role": "agent",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "external_user_id": "string",
  • "display_name": "string",
  • "email": "user@example.com",
  • "role": "agent",
  • "active": true,
  • "created_at": "2026-10-12T09:41:07Z"
}

Keys

Claves de API por tenant.

Listar claves de API del tenant

Nunca devuelve el valor completo, solo el prefijo.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Crear una clave de API para el tenant

El valor completo se devuelve una sola vez. Los alcances no pueden superar los de la clave que la crea.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
name
string <= 100 characters
scopes
required
Array of strings (Scope) non-empty
Items Enum: "messages:send" "messages:read" "conversations:read" "conversations:write" "contacts:write" "templates:read" "templates:write" "numbers:read" "numbers:write" "agents:write" "keys:write" "usage:read" "settings:write" "webhooks:write" "embed:create"
rate_limit_per_min
integer [ 1 .. 100000 ]
Default: 600
expires_at
string <date-time> (Timestamp)

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "scopes": [
    ],
  • "rate_limit_per_min": 600,
  • "expires_at": "2026-10-12T09:41:07Z"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "prefix": "string",
  • "app_id": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "scopes": [
    ],
  • "rate_limit_per_min": 1,
  • "last_used_at": "2026-10-12T09:41:07Z",
  • "expires_at": "2026-10-12T09:41:07Z",
  • "revoked_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "key": "wak_live_7Hq2xK9d_9f3a0c1e5b7d4a2f8c6e0b1d3a5f7c9e2b4d6f8a"
}

Revocar una clave

Authorizations:
ApiKeyEmbedSession
path Parameters
key_id
required
string (ApiKeyId) ^key_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Usage

Costes, uso y licencia del tenant.

Costes de Meta

Datos de pricing_analytics de Meta guardados en usage_cost_daily. Con facturación meta_direct es informativo: la factura la emite Meta al cliente. Con línea de crédito de un Solution Partner Meta no devuelve coste.

Authorizations:
ApiKeyEmbedSession
query Parameters
from
required
string <date>
to
required
string <date>
group_by
Array of strings
Items Enum: "day" "category" "pricing_type" "country" "number"

Dimensiones separadas por comas.

header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "currency": "string",
  • "synced_at": "2026-10-12T09:41:07Z",
  • "from": "2019-08-24",
  • "to": "2019-08-24",
  • "totals": {
    },
  • "data": [
    ]
}

Mensajes propios por día y estado

Datos del propio gateway, sin retraso respecto de Meta.

Authorizations:
ApiKeyEmbedSession
query Parameters
from
required
string <date>
to
required
string <date>
group_by
Array of strings
Items Enum: "day" "status" "direction" "type"
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "from": "2019-08-24",
  • "to": "2019-08-24",
  • "data": [
    ]
}

Licencia, límites y consumo del tenant

Permite a la app anfitriona ocultar entradas de menú antes de cargar una pantalla no contratada.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "module": "whatsapp",
  • "status": "trial",
  • "valid_from": "2026-10-12T09:41:07Z",
  • "valid_until": "2026-10-12T09:41:07Z",
  • "limits": {
    },
  • "usage": {
    }
}

Settings

Ajustes del tenant.

Ajustes del tenant

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "auto_assign_mode": "manual",
  • "reopen_on_inbound": "unassigned",
  • "optout_keywords": [
    ],
  • "enforce_opt_in": false,
  • "cost_alert_monthly": 0,
  • "notify_email": "user@example.com"
}

Cambiar ajustes

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
non-empty
auto_assign_mode
string
Enum: "manual" "round_robin" "least_busy"
reopen_on_inbound
string
Enum: "unassigned" "previous_agent"
optout_keywords
Array of strings <= 20 items [ items <= 50 characters ]
enforce_opt_in
boolean
cost_alert_monthly
number or null >= 0
notify_email
string or null <email>

Responses

Request samples

Content type
application/json
{
  • "auto_assign_mode": "manual",
  • "reopen_on_inbound": "unassigned",
  • "optout_keywords": [
    ],
  • "enforce_opt_in": true,
  • "cost_alert_monthly": 0,
  • "notify_email": "user@example.com"
}

Response samples

Content type
application/json
{
  • "auto_assign_mode": "manual",
  • "reopen_on_inbound": "unassigned",
  • "optout_keywords": [
    ],
  • "enforce_opt_in": false,
  • "cost_alert_monthly": 0,
  • "notify_email": "user@example.com"
}

Webhooks

Destinos de eventos salientes hacia vuestras apps.

Listar destinos de eventos

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Registrar un destino de eventos

Solo https, sin redirecciones y sin direcciones privadas. La respuesta incluye secret una sola vez. La suscripción es siempre del tenant de la llamada. Para recibir los eventos de todos los tenants de una app se usa POST /admin/v1/apps/{app_id}/webhook-subscriptions.

Authorizations:
ApiKeyEmbedSession
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
url
required
string <uri> ^https://

Solo https.

events
required
Array of strings (EventPattern) non-empty [ items^(\*|[a-z_]+(\.[a-z_]+)*(\.\*)?)$ ]

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "app_id": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "events": [
    ],
  • "active": true,
  • "consecutive_failures": 0,
  • "created_at": "2026-10-12T09:41:07Z",
  • "secret": "string"
}

Editar o reactivar una suscripción

Authorizations:
ApiKeyEmbedSession
path Parameters
subscription_id
required
string (SubscriptionId) ^whs_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
non-empty
url
string <uri> ^https://
events
Array of strings (EventPattern) non-empty [ items^(\*|[a-z_]+(\.[a-z_]+)*(\.\*)?)$ ]
active
boolean

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "app_id": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "events": [
    ],
  • "active": true,
  • "consecutive_failures": 0,
  • "created_at": "2026-10-12T09:41:07Z"
}

Borrar una suscripción

Authorizations:
ApiKeyEmbedSession
path Parameters
subscription_id
required
string (SubscriptionId) ^whs_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Enviar un evento de prueba

Authorizations:
ApiKeyEmbedSession
path Parameters
subscription_id
required
string (SubscriptionId) ^whs_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "subscription_id": "string",
  • "event_id": "string",
  • "event_type": "whatsapp.message.received",
  • "status": "pending",
  • "attempts": 0,
  • "next_attempt_at": "2026-10-12T09:41:07Z",
  • "last_status_code": 0,
  • "last_error": "string",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Entregas y reintentos

Authorizations:
ApiKeyEmbedSession
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

status
string (DeliveryStatus)
Enum: "pending" "delivered" "failed" "dead"
subscription_id
string (SubscriptionId) ^whs_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Reenviar una entrega

Authorizations:
ApiKeyEmbedSession
path Parameters
delivery_id
required
string (DeliveryId) ^dlv_[0-9a-f]{32}$
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "subscription_id": "string",
  • "event_id": "string",
  • "event_type": "whatsapp.message.received",
  • "status": "pending",
  • "attempts": 0,
  • "next_attempt_at": "2026-10-12T09:41:07Z",
  • "last_status_code": 0,
  • "last_error": "string",
  • "delivered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z"
}

Embed

Tokens y sesiones de la UI embebible.

Emitir un token para una pantalla embebida

Lo pide el backend de la app anfitriona; nunca el navegador. El role que envía la app es el que manda. El token dura como máximo 5 minutos, es de un solo uso y va en el fragmento de la URL.

Authorizations:
ApiKey
header Parameters
X-Tenant-Id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Obligatoria con claves multi-tenant (o X-Tenant-Ref). Se ignora con una clave fijada a un tenant.

X-Tenant-Ref
string <= 200 characters

external_ref del tenant en vuestro sistema. Alternativa a X-Tenant-Id.

Request Body schema: application/json
required
screen
required
string (EmbedScreen)
Enum: "chat" "templates" "settings" "costs" "signup"
required
object (EmbedUser)
object

Parámetros de la pantalla (conversation_id, contact_ref, template_id, tab, from, to).

locale
string
Default: "es"
Enum: "es" "en"
ttl_seconds
integer [ 30 .. 300 ]
Default: 300

Responses

Request samples

Content type
application/json
{
  • "screen": "chat",
  • "user": {
    },
  • "params": {
    },
  • "locale": "es",
  • "ttl_seconds": 300
}

Response samples

Content type
application/json
{}

Canjear un token de embebido por un access token

El iframe lo llama al cargar. Gasta el token de embebido y devuelve un access_token de 15 minutos que vive solo en memoria.

Request Body schema: application/json
required
token
required
string

Responses

Request samples

Content type
application/json
{
  • "token": "string"
}

Response samples

Content type
application/json
{
  • "access_token": "string",
  • "expires_at": "2026-10-12T09:41:07Z",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "agent_id": "string",
  • "role": "agent",
  • "screen": "chat",
  • "params": {
    },
  • "features": [
    ],
  • "allowed_origins": [
    ]
}

Admin

API de administración (solo vuestro equipo).

Listar tenants

Authorizations:
AdminToken
query Parameters
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string <= 500 characters

Valor next_cursor de la página anterior.

status
string (TenantStatus)
Enum: "active" "suspended" "closed"
q
string

Busca por nombre o external_ref.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Crear un tenant

Se crea sin licencia. Hasta fijarla con PUT .../license, todas las llamadas del tenant devuelven 403 license_inactive.

Authorizations:
AdminToken
header Parameters
Idempotency-Key
string [ 8 .. 200 ] characters

Misma clave y mismo cuerpo devuelve la respuesta original durante 24 h; mismo cuerpo distinto devuelve 409 idempotency_conflict.

Request Body schema: application/json
required
external_ref
required
string [ 1 .. 200 ] characters
name
required
string [ 1 .. 200 ] characters
default_locale
string
Default: "es"
timezone
string
Default: "Europe/Madrid"
data_retention_days
integer >= 1
Default: 365

Responses

Request samples

Content type
application/json
{
  • "external_ref": "CLI-0042",
  • "name": "Clínica Dental Sol",
  • "default_locale": "es",
  • "timezone": "Europe/Madrid"
}

Response samples

Content type
application/json
{
  • "id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "external_ref": "string",
  • "name": "string",
  • "status": "active",
  • "default_locale": "string",
  • "timezone": "string",
  • "data_retention_days": 1,
  • "created_at": "2026-10-12T09:41:07Z"
}

Detalle de un tenant

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Responses

Response samples

Content type
application/json
{
  • "id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "external_ref": "string",
  • "name": "string",
  • "status": "active",
  • "default_locale": "string",
  • "timezone": "string",
  • "data_retention_days": 1,
  • "created_at": "2026-10-12T09:41:07Z",
  • "license": {
    },
  • "apps": [
    ],
  • "account": {
    }
}

Editar un tenant

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
Request Body schema: application/json
required
non-empty
name
string [ 1 .. 200 ] characters
status
string (TenantStatus)
Enum: "active" "suspended" "closed"
default_locale
string
timezone
string
data_retention_days
integer >= 1

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "status": "active",
  • "default_locale": "string",
  • "timezone": "string",
  • "data_retention_days": 1
}

Response samples

Content type
application/json
{
  • "id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "external_ref": "string",
  • "name": "string",
  • "status": "active",
  • "default_locale": "string",
  • "timezone": "string",
  • "data_retention_days": 1,
  • "created_at": "2026-10-12T09:41:07Z"
}

Fijar la licencia del módulo WhatsApp

Reemplaza la licencia. Invalida la caché al instante y emite license.updated. Se registra en audit_log con el usuario de vuestro equipo.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
Request Body schema: application/json
required
status
required
string (LicenseStatus)
Enum: "trial" "active" "suspended" "expired"
valid_from
string <date-time> (Timestamp)
Timestamp (string) or null
object (LicenseLimits)
notes
string <= 1000 characters

Responses

Request samples

Content type
application/json
{
  • "status": "active",
  • "valid_until": "2027-10-12T00:00:00Z",
  • "limits": {
    }
}

Response samples

Content type
application/json
{
  • "module": "whatsapp",
  • "status": "trial",
  • "valid_from": "2026-10-12T09:41:07Z",
  • "valid_until": "2026-10-12T09:41:07Z",
  • "limits": {
    },
  • "usage": {
    }
}

Suspender un tenant

Pone la licencia en suspended. Los envíos en cola pasan a failed con license_inactive.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
Request Body schema: application/json
optional
reason
string <= 500 characters

Responses

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "module": "whatsapp",
  • "status": "trial",
  • "valid_from": "2026-10-12T09:41:07Z",
  • "valid_until": "2026-10-12T09:41:07Z",
  • "limits": {
    },
  • "usage": {
    }
}

Habilitar o deshabilitar una app para un tenant

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
app_id
required
string (AppId) ^app_[0-9a-f]{32}$
Request Body schema: application/json
required
enabled
required
boolean

Responses

Request samples

Content type
application/json
{
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "app_id": "string",
  • "code": "string",
  • "enabled": true
}

Conectar un número a mano con un token

Para desarrollo y soporte: asocia una WABA y un número ya existentes usando un token de acceso que se guarda cifrado. No sustituye al Embedded Signup. Comprueba el token con debug_token y lee el número y la WABA. Se desactiva con ALLOW_MANUAL_CONNECT=false.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
Request Body schema: application/json
required
waba_id
required
string
phone_number_id
required
string
access_token
required
string

Token con whatsapp_business_messaging y whatsapp_business_management. Se guarda cifrado.

billing_mode
string (BillingMode)
Enum: "meta_direct" "platform_credit_line"
onboarding_type
string
Default: "dedicated"
Enum: "dedicated" "business_app"

business_app si el número también está en la app WhatsApp Business: no se registra y se pide la sincronización de contactos e historial.

two_step_pin
string^[0-9]{6}$

PIN de 6 dígitos si el número ya estaba registrado.

is_default
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "waba_id": "string",
  • "phone_number_id": "string",
  • "access_token": "string",
  • "billing_mode": "meta_direct",
  • "onboarding_type": "dedicated",
  • "two_step_pin": "string",
  • "is_default": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Exportar los datos de un tenant

Genera un fichero con todos sus datos para la baja. Responde 202 con el identificador del trabajo.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Responses

Response samples

Content type
application/json
{
  • "job_id": "string",
  • "status": "queued"
}

Listar apps

Authorizations:
AdminToken

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Registrar una app de vuestro ecosistema

Authorizations:
AdminToken
Request Body schema: application/json
required
code
required
string^[a-z0-9_-]{2,40}$
name
required
string [ 1 .. 200 ] characters
allowed_origins
Array of strings <uri> [ items <uri > ]

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "code": "string",
  • "name": "string",
  • "allowed_origins": [],
  • "status": "active",
  • "created_at": "2026-10-12T09:41:07Z"
}

Editar una app

Cambiar allowed_origins actualiza las cabeceras frame-ancestors de la UI embebible.

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$
Request Body schema: application/json
required
non-empty
name
string [ 1 .. 200 ] characters
allowed_origins
Array of strings <uri> [ items <uri > ]
status
string
Enum: "active" "disabled"

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "code": "string",
  • "name": "string",
  • "allowed_origins": [],
  • "status": "active",
  • "created_at": "2026-10-12T09:41:07Z"
}

Listar las claves de una app

Nunca devuelve el valor completo, solo el prefijo. Incluye las revocadas.

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Crear una clave de API para una app

Sin tenant_id la clave es multi-tenant y exige X-Tenant-Id o X-Tenant-Ref en cada llamada. El valor completo se devuelve una sola vez.

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$
Request Body schema: application/json
required
name
string <= 100 characters
tenant_id
string (TenantId) ^ten_[0-9a-f]{32}$
scopes
required
Array of strings (Scope) non-empty
Items Enum: "messages:send" "messages:read" "conversations:read" "conversations:write" "contacts:write" "templates:read" "templates:write" "numbers:read" "numbers:write" "agents:write" "keys:write" "usage:read" "settings:write" "webhooks:write" "embed:create"
rate_limit_per_min
integer [ 1 .. 100000 ]
Default: 600
expires_at
string <date-time> (Timestamp)

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "scopes": [
    ],
  • "rate_limit_per_min": 600,
  • "expires_at": "2026-10-12T09:41:07Z"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "prefix": "string",
  • "app_id": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "scopes": [
    ],
  • "rate_limit_per_min": 1,
  • "last_used_at": "2026-10-12T09:41:07Z",
  • "expires_at": "2026-10-12T09:41:07Z",
  • "revoked_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "key": "wak_live_7Hq2xK9d_9f3a0c1e5b7d4a2f8c6e0b1d3a5f7c9e2b4d6f8a"
}

Listar las suscripciones de una app

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Suscripción de toda una app a los eventos

Recibe los eventos de todos los tenants para los que la app está habilitada. El secreto se devuelve una sola vez.

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$
Request Body schema: application/json
required
url
required
string <uri> ^https://

Solo https.

events
required
Array of strings (EventPattern) non-empty [ items^(\*|[a-z_]+(\.[a-z_]+)*(\.\*)?)$ ]

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "app_id": "string",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "events": [
    ],
  • "active": true,
  • "consecutive_failures": 0,
  • "created_at": "2026-10-12T09:41:07Z",
  • "secret": "string"
}

Configuración de la plataforma

Qué parámetros de Meta y de la plataforma están configurados. Nunca devuelve secretos, solo si existen.

Authorizations:
AdminToken

Responses

Response samples

Content type
application/json
{
  • "environment": "string",
  • "public_base_url": "string",
  • "graph_version": "string",
  • "manual_connect_enabled": true,
  • "allow_private_webhook_urls": true,
  • "meta": {
    }
}

Cuenta de WhatsApp y números de un tenant

Parámetros del WABA, estado del token y números conectados. El token nunca se devuelve.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b

Responses

Response samples

Content type
application/json
{
  • "account": {
    },
  • "credential": {
    },
  • "numbers": [
    ]
}

Fijar el número predeterminado

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$
Request Body schema: application/json
required
is_default
required
boolean
Value: true

Responses

Request samples

Content type
application/json
{
  • "is_default": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Desconectar un número

Deja de enviar y recibir por ese número en la plataforma. No lo da de baja en Meta.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Releer un número desde Meta

Actualiza calidad, límite, nombre y estado con el token del tenant. Si Meta rechaza el token, queda marcado como inválido.

Authorizations:
AdminToken
path Parameters
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
number_id
required
string (NumberId) ^num_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "phone_number_id": "string",
  • "display_phone_number": "string",
  • "verified_name": "string",
  • "name_status": "string",
  • "quality_rating": "string",
  • "messaging_limit": "string",
  • "platform_type": "string",
  • "throughput_level": "string",
  • "status": "pending",
  • "onboarding_type": "dedicated",
  • "is_on_biz_app": true,
  • "history_sync": {
    },
  • "is_default": true,
  • "registered_at": "2026-10-12T09:41:07Z",
  • "created_at": "2026-10-12T09:41:07Z",
  • "updated_at": "2026-10-12T09:41:07Z"
}

Revocar cualquier clave de API

Sirve también para las claves multi-tenant, que un tenant no puede revocar.

Authorizations:
AdminToken
path Parameters
key_id
required
string (ApiKeyId) ^key_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Eliminar una suscripción de una app

Authorizations:
AdminToken
path Parameters
app_id
required
string (AppId) ^app_[0-9a-f]{32}$
subscription_id
required
string (SubscriptionId) ^whs_[0-9a-f]{32}$

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Registro de auditoría

Cambios hechos por administración, apps y agentes. Del más reciente al más antiguo.

Authorizations:
AdminToken
query Parameters
tenant_id
string (TenantId) ^ten_[0-9a-f]{32}$
Examples: tenant_id=ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b
limit
integer [ 1 .. 200 ]
Default: 50
cursor
string^[0-9]{1,18}$

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "next_cursor": "string"
}

Estado operativo

Colas, trabajos en dead, números con problemas y pagos bloqueados.

Authorizations:
AdminToken

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "checked_at": "2026-10-12T09:41:07Z",
  • "queues": {
    },
  • "webhook_events": {
    },
  • "deliveries": {
    },
  • "payment_blocked": [
    ],
  • "numbers_with_problems": [
    ]
}

Reprocesar eventos de Meta

Vuelve a poner en cola los eventos de Meta guardados en un rango, normalmente los failed.

Authorizations:
AdminToken
Request Body schema: application/json
required
from
required
string <date-time> (Timestamp)
to
required
string <date-time> (Timestamp)
status
string
Default: "failed"
Enum: "failed" "received" "ignored"

Responses

Request samples

Content type
application/json
{
  • "from": "2026-10-12T09:41:07Z",
  • "to": "2026-10-12T09:41:07Z",
  • "status": "failed"
}

Response samples

Content type
application/json
{
  • "requeued": 0
}

Meta

Endpoint que recibe los webhooks de Meta (servicio ingest).

Verificación del webhook de Meta

Si hub.mode es subscribe y hub.verify_token coincide, devuelve hub.challenge en texto plano.

query Parameters
hub.mode
string
hub.verify_token
string
hub.challenge
string

Responses

Recepción de eventos de Meta

Valida X-Hub-Signature-256 (HMAC-SHA256 del cuerpo sin parsear con el APP_SECRET), guarda cada elemento de entry[].changes[] en inbound_webhook_event con deduplicación y responde 200 en menos de un segundo. Una firma inválida devuelve 401.

Authorizations:
MetaSignature
header Parameters
X-Hub-Signature-256
string

sha256=. Si falta o no coincide la respuesta es 401 (no 422).

Request Body schema: application/json
optional
object
string
Value: "whatsapp_business_account"
Array of objects

Responses

Request samples

Content type
application/json
{
  • "object": "whatsapp_business_account",
  • "entry": [
    ]
}

Health

Comprobaciones de salud.

El proceso está vivo

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "checks": {
    }
}

El proceso puede atender tráfico

Comprueba la conexión con la base de datos.

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "checks": {
    }
}

Llega un mensaje de un contacto Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "whatsapp.message.received"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.message.received",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Una persona escribe desde la app del móvil Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "whatsapp.message.sent_from_app"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.message.sent_from_app",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Un envío pasa a sent, delivered, read o failed Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "whatsapp.message.status"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.message.status",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Se asigna o reasigna una conversación Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.conversation.assigned",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Se cierra una conversación Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.conversation.assigned",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Se reabre una conversación Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.conversation.assigned",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Meta aprueba, rechaza, pausa o desactiva una plantilla Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.template.status_changed",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Meta cambia la calidad de una plantilla Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.template.status_changed",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Meta cambia la categoría de una plantilla Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.template.status_changed",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Termina el alta de un número Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.number.connected",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Cambia la calidad, el límite o el estado de un número Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.number.connected",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Se desconecta un número Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.number.connected",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

La WABA queda bloqueada por pago en Meta Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.account.payment_blocked",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

La WABA vuelve a tener el pago activo Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.account.payment_blocked",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Meta limita la cuenta Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.account.payment_blocked",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Falla un alta de número Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "whatsapp.signup.failed"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.signup.failed",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

El gasto del mes llega al 80 % o al 100 % de lo fijado Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "whatsapp.usage.alert"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "whatsapp.usage.alert",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}

Cambia el estado o los límites de la licencia Webhook

Authorizations:
ApiKey
Request Body schema: application/json
required
id
required
string (EventId) ^evt_[0-9a-f]{32}$
type
required
string
Enum: "whatsapp.message.received" "whatsapp.message.sent_from_app" "whatsapp.message.status" "whatsapp.conversation.assigned" "whatsapp.conversation.closed" "whatsapp.conversation.reopened" "whatsapp.template.status_changed" "whatsapp.template.quality_changed" "whatsapp.template.category_changed" "whatsapp.number.connected" "whatsapp.number.updated" "whatsapp.number.disconnected" "whatsapp.account.payment_blocked" "whatsapp.account.payment_active" "whatsapp.account.restricted" "whatsapp.signup.failed" "whatsapp.usage.alert" "whatsapp.test" "license.updated"
Value: "license.updated"
tenant_id
required
string (TenantId) ^ten_[0-9a-f]{32}$
tenant_ref
required
string

external_ref del tenant para localizar al cliente sin consultar.

occurred_at
required
string <date-time> (Timestamp)
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "type": "license.updated",
  • "tenant_id": "ten_018f3c5a9b2d7e4f8a1b2c3d4e5f6a7b",
  • "tenant_ref": "string",
  • "occurred_at": "2026-10-12T09:41:07Z",
  • "data": {
    }
}