# API de ManyContacts — Documentación para desarrolladores

Canonical: https://www.manycontacts.com/es/api/

Desarrolladores

# API de ManyContacts

 Integra WhatsApp en tus aplicaciones: envía mensajes, gestiona contactos y recibe eventos en tiempo real mediante webhooks. Una API REST sencilla sobre HTTPS que devuelve JSON.

 Consigue tu API key
 Ver especificación OpenAPI

 Contenido

- Autenticación

- Límites de uso

- Errores

-

 Mensajes

- POST /message/text

- POST /message/media

- POST /message/note

- POST /message/interactive

-

 Contactos (v1)

- GET /contacts

- GET /contact/:id

- GET /contact/phone/:phone

- POST /contact

- PUT /contact/:id

- PUT /contact/:id/customField

- POST /contact/:id/assign

- POST /contact/:id/unassign

- POST /contact/:id/close

- POST /contact/:id/open

- POST /contact/:id/tag/:tagId

- DEL /contact/:id/tag/:tagId

- POST /contact/:id/team/:teamId

- DEL /contact/:id/team/:teamId

- GET /contact/:id/bot/init

-

 Contactos (v2)

- GET /contact/:phone

- PUT /contact/:phone

- PUT /contact/:phone/customField

- POST /contact/:phone/assign

- POST /contact/:phone/unassign

- POST /contact/:phone/close

- POST /contact/:phone/open

- POST /contact/:phone/tag/:tagId

- POST /contact/:phone/tag/name/:tagName

- DEL /contact/:phone/tag/:tagId

- POST /contact/:phone/team/:teamId

- DEL /contact/:phone/team/:teamId

- GET /contact/:phone/bot/init

- PUT /contact/:phone/stage/:column

-

 Etiquetas

- GET /tags

- POST /tag

- PUT /tag/:id

- DEL /tag/:id

-

 Equipos

- GET /teams

-

 Plantillas (v1)

- GET /templates

- POST /template/:name/:number

- POST /template/:name/:number/media

-

 Plantillas (v2)

- POST /template/:name/:number

- POST /template/:name/:number/media

-

 Usuarios

- GET /users

- Webhooks

## Autenticación

 Todas las llamadas se hacen sobre HTTPS contra la URL base de la API. Las respuestas se devuelven en formato JSON.

 Base URL: https://api.manycontacts.com
 La autenticación se realiza mediante una cabecera HTTP apikey con la clave de tu organización. Cada petición debe incluir esta cabecera.

 curl https://api.manycontacts.com/v1/contacts \
 -H "apikey: TU_API_KEY"
 Encuentra (y regenera) tu API key en la app: Ajustes → Desarrolladores. La clave no está disponible durante el periodo de prueba.

## Límites de uso

 Las peticiones están limitadas por organización dentro de una ventana de 60 segundos, según tu plan:

 | Plan| Límite|

 | Cuenta de pago| 60 req / min|

 | Cuenta gratuita / en prueba| 10 req / min|

 Al superar el límite, la API responde con un código 429. El campo TTL indica los segundos que faltan para poder reintentar.

 HTTP/1.1 429 Too Many Requests
{ "error": "Too many requests. Try again after sometime or contact support@manycontacts.com. TTL42" }

## Errores y códigos de estado

 La API usa códigos de estado HTTP estándar. Los endpoints más recientes devuelven además un cuerpo JSON con un campo error (y, cuando aplica, detail).

 | Código| Significado|

 | 200| Correcto. La operación se ha realizado.|

 | 400| Petición inválida: faltan parámetros o son incorrectos.|

 | 401| No autorizado: falta la cabecera apikey o no es válida.|

 | 402| Pago requerido: sin créditos de IA disponibles.|

 | 404| No encontrado: el recurso indicado no existe.|

 | 422| No procesable: la operación no es posible en el estado actual (p. ej. gateway no compatible).|

 | 429| Demasiadas peticiones: se ha superado el límite de uso.|

 | 500| Error interno del servidor.|

 Los endpoints antiguos pueden devolver un código de estado sin cuerpo JSON. Cuando el mensaje se envía pero el proveedor (Meta) devuelve un aviso, la respuesta es 200 con el detalle dentro del campo error.

## Mensajes

 Envía mensajes de WhatsApp a tus contactos. Puedes identificar al contacto por su número de teléfono o por su ID.

### POST /v1/message/text

 Envía un mensaje de texto. Si el contacto no existe, se crea automáticamente.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | text| string| Sí| Cuerpo del mensaje.|

 | number| string| Condicional| Teléfono del contacto en formato internacional, sin el símbolo '+'. Obligatorio si no se envía contactid.|

 | contactid| string| Condicional| ID (UUID) del contacto. Alternativa a number.|

 | conchi_user_id| string| No| ID de un usuario de IA de la organización, para atribuir el mensaje al agente.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/message/text \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "number": "34600111222", "text": "Hola 👋" }'
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

### POST /v1/message/media

 Envía un archivo (imagen, audio, vídeo o documento) como adjunto multipart. El tipo se detecta a partir del archivo.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | number| string| Sí| Teléfono del contacto en formato internacional, sin el símbolo '+'. Obligatorio si no se envía contactid.|

 | file| file (multipart)| Sí| Archivo a enviar (multipart/form-data).|

 | caption| string| No| Texto que acompaña al archivo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/message/media \
 -H "apikey: TU_API_KEY" \
 -F "number=34600111222" \
 -F "caption=Tu factura" \
 -F "file=@factura.pdf"
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

### POST /v1/message/note

 Añade una nota interna a la conversación del contacto (no se envía al cliente).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | number| string| Sí| Teléfono del contacto en formato internacional, sin el símbolo '+'. Obligatorio si no se envía contactid.|

 | text| string| Sí| Contenido de la nota.|

 | hidden| boolean| No| Si es true, la nota no marca la conversación como pendiente.|

 | tagId| string| No| ID de una etiqueta a asignar al contacto junto con la nota.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/message/note \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "number": "34600111222", "text": "Cliente VIP, priorizar respuesta", "hidden": true }'
 Ejemplo de respuesta

 {
 "id": "3b1e...",
 "type": 2,
 "contact_id": "8f3c...",
 "timestamp": "2026-07-09T13:00:00.000Z",
 "text": "Cliente VIP, priorizar respuesta"
}

### POST /v1/message/interactive

 Envía un mensaje interactivo con botones de respuesta rápida o una lista de opciones. Según el número de botones, ManyContacts elige automáticamente el formato adecuado.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | text| string| Sí| Cuerpo del mensaje.|

 | buttons| string[]| Sí| Lista de títulos de los botones (de 1 a 10). Con 1-3 botones se envían botones de respuesta (máx. 20 caracteres); con 4-10 se genera una lista (máx. 24 caracteres).|

 | number| string| Condicional| Teléfono del contacto en formato internacional, sin el símbolo '+'. Obligatorio si no se envía contactid.|

 | contactid| string| Condicional| ID (UUID) del contacto. Alternativa a number.|

 | header| string| No| Cabecera opcional del mensaje (máx. 60 caracteres).|

 | footer| string| No| Pie opcional del mensaje (máx. 60 caracteres).|

 | cta| string| No| Texto del botón que abre la lista (solo en modo lista, máx. 20 caracteres). Por defecto: 'Ver opciones'.|

 Requiere que la organización use WhatsApp API o WhatsApp Coexistence (gateway de Meta) y que el contacto haya escrito en las últimas 24 horas (ventana de servicio de Meta).

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/message/interactive \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "number": "34600111222",
 "text": "¿Confirmas tu cita?",
 "header": "Recordatorio",
 "footer": "Clínica ManyContacts",
 "buttons": ["Sí, confirmo", "Reprogramar", "Cancelar"]
 }'
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }
 Errores específicos

 | Código| error| Significado|

 | 400| invalid_parameters| Faltan parámetros o no cumplen las validaciones (texto vacío, número de botones fuera de rango, longitudes excedidas...).|

 | 404| contact_not_found| No existe ningún contacto con ese número o ID.|

 | 422| gateway_not_supported| La organización no tiene WhatsApp API ni Coexistence habilitados.|

 | 422| outside_24h_window| El contacto está fuera de la ventana de 24 horas de Meta. Usa una plantilla para reabrir la conversación.|

## Contactos (v1)

 Gestiona tus contactos por ID (UUID). La mayoría de acciones que reciben un número crean el contacto automáticamente si no existe.

 Nota: los endpoints que reciben un número crean el contacto automáticamente (source: 'api') si no existe.

 Los endpoints que devuelven un contacto usan esta forma (campos principales):

 {
 "id": "8f3c...",
 "name": "Juan",
 "email": null,
 "open": true,
 "last_user_id": null,
 "number": "34600111222",
 "notes": null,
 "locked": false,
 "customFields": {},
 "tags": [{ "id": "a1b2...", "name": "Cliente", "color": "#55efc4" }]
}

### GET /v1/contacts

 Lista de contactos con filtros (asignación, página, cerrados, usuarios, etiquetas).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | filter| integer (query)| No| 0 = solo chats sin asignar y abiertos; 1 = todos los chats.|

 | page| integer (query)| No| Página de resultados.|

 | closed| boolean (query)| No| Si es 'true', devuelve solo conversaciones cerradas.|

 | users| string[] (query)| No| Filtra por IDs de usuario asignado (parámetro repetible).|

 | tags| string[] (query)| No| Filtra por IDs de etiqueta; el contacto debe tener todas (parámetro repetible).|

 Ejemplo de petición

 curl "https://api.manycontacts.com/v1/contacts?filter=1&page=0&closed=false" \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 [
 {
 "id": "8f3c...",
 "name": "Juan",
 "email": null,
 "open": true,
 "last_user_id": null,
 "number": "34600111222",
 "notes": null,
 "locked": false,
 "customFields": {},
 "tags": []
 }
]

### GET /v1/contact/:id

 Obtiene un contacto por su ID.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/contact/8f3c... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": true, "tags": [] }

### GET /v1/contact/phone/:phone

 Obtiene un contacto por su número de teléfono.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Si no existe ningún contacto con ese número, devuelve un objeto vacío { }.

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/contact/phone/34600111222 \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": true, "tags": [] }

### POST /v1/contact

 Crea un contacto (o devuelve el existente). Requiere number.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | number| string| Sí| Teléfono del contacto en formato internacional, sin el símbolo '+'. Obligatorio si no se envía contactid.|

 | name| string| No| Nombre del contacto.|

 | assigned| string| No| ID del usuario al que asignar el contacto al crearlo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "number": "34600111222", "name": "Juan" }'
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": true, "tags": [] }

### PUT /v1/contact/:id

 Actualiza campos del contacto: name, number, open, notes, email, locked.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | name| string| No| Nombre del contacto.|

 | number| string| No| Nuevo número de teléfono del contacto.|

 | open| boolean| No| Estado de la conversación (true = abierta).|

 | notes| string| No| Notas del contacto.|

 | email| string| No| Email del contacto.|

 | locked| boolean| No| Si el contacto está bloqueado.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v1/contact/8f3c... \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "name": "Juan Pérez", "email": "juan@example.com" }'
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

### PUT /v1/contact/:id/customField

 Crea o actualiza un campo personalizado (key + value).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | key| string| Sí| Nombre del campo personalizado.|

 | value| string| Sí| Valor del campo personalizado.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v1/contact/8f3c.../customField \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "key": "dni", "value": "12345678Z" }'
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

### POST /v1/contact/:id/assign/:userId

 Asigna el contacto a un usuario.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | userId| string (path)| Sí| ID del usuario (agente) al que asignar el contacto.|

 Si el usuario es un agente de IA y la organización no tiene créditos de IA, devuelve 402 con { "error": "no_ai_credits" }.

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../assign/5d2a... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "last_user_id": "5d2a...", "open": true, "tags": [] }

### POST /v1/contact/:id/unassign

 Quita la asignación del contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../unassign \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "last_user_id": null, "open": true, "tags": [] }

### POST /v1/contact/:id/close

 Cierra la conversación del contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../close \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": false, "tags": [] }

### POST /v1/contact/:id/open

 Abre la conversación del contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../open \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": true, "tags": [] }

### POST /v1/contact/:id/tag/:tagId

 Añade una etiqueta al contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | tagId| string (path)| Sí| ID de la etiqueta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../tag/a1b2... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [{ "id": "a1b2...", "name": "Cliente", "color": "#55efc4" }] }

### DELETE /v1/contact/:id/tag/:tagId

 Quita una etiqueta del contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | tagId| string (path)| Sí| ID de la etiqueta.|

 Ejemplo de petición

 curl -X DELETE https://api.manycontacts.com/v1/contact/8f3c.../tag/a1b2... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### POST /v1/contact/:id/team/:teamId

 Asigna el contacto a un equipo.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | teamId| string (path)| Sí| ID del equipo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/contact/8f3c.../team/7c9d... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### DELETE /v1/contact/:id/team/:teamId

 Quita el contacto de un equipo.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 | teamId| string (path)| Sí| ID del equipo.|

 Ejemplo de petición

 curl -X DELETE https://api.manycontacts.com/v1/contact/8f3c.../team/7c9d... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### GET /v1/contact/:id/bot/init

 Lanza el primer mensaje del chatbot al contacto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID (UUID) del contacto, en la ruta.|

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/contact/8f3c.../bot/init \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

## Contactos (v2)

 La API v2 identifica al contacto directamente por su número de teléfono en la ruta, en lugar de por ID. Incluye los mismos endpoints de asignación, etiquetas, equipos, apertura/cierre y campos personalizados que la v1, además de estos específicos:

### GET /v2/contact/:phone

 Obtiene el contacto (incluye notas internas) por teléfono.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Ejemplo de petición

 curl https://api.manycontacts.com/v2/contact/34600111222 \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 {
 "id": "8f3c...",
 "name": "Juan",
 "number": "34600111222",
 "open": true,
 "tags": [],
 "internal_notes": [
 { "text": "Cliente VIP", "createdAt": "2026-07-09T13:00:00.000Z" }
 ]
}

### PUT /v2/contact/:phone

 Crea o actualiza el contacto por teléfono.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | name| string| No| Nombre del contacto.|

 | open| boolean| No| Estado de la conversación (true = abierta).|

 | notes| string| No| Notas del contacto.|

 | email| string| No| Email del contacto.|

 | locked| boolean| No| Si el contacto está bloqueado.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v2/contact/34600111222 \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "name": "Juan Pérez", "email": "juan@example.com" }'
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan Pérez", "number": "34600111222", "email": "juan@example.com", "open": true, "tags": [] }

### PUT /v2/contact/:phone/customField

 Crea o actualiza un campo personalizado (crea el contacto si no existe).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | key| string| Sí| Nombre del campo personalizado.|

 | value| string| Sí| Valor del campo personalizado.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v2/contact/34600111222/customField \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "key": "dni", "value": "12345678Z" }'
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "customFields": { "dni": "12345678Z" }, "tags": [] }

### POST /v2/contact/:phone/assign/:userId

 Asigna el contacto (por teléfono) a un usuario.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | userId| string (path)| Sí| ID del usuario (agente) al que asignar el contacto.|

 Si el usuario es un agente de IA y la organización no tiene créditos de IA, devuelve 402 con { "error": "no_ai_credits" }.

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/assign/5d2a... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "last_user_id": "5d2a...", "open": true, "tags": [] }

### POST /v2/contact/:phone/unassign

 Quita la asignación del contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/unassign \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "last_user_id": null, "open": true, "tags": [] }

### POST /v2/contact/:phone/close

 Cierra la conversación del contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/close \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": false, "tags": [] }

### POST /v2/contact/:phone/open

 Abre la conversación del contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/open \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "open": true, "tags": [] }

### POST /v2/contact/:phone/tag/:tagId

 Añade una etiqueta al contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | tagId| string (path)| Sí| ID de la etiqueta.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/tag/a1b2... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [{ "id": "a1b2...", "name": "Cliente", "color": "#55efc4" }] }

### POST /v2/contact/:phone/tag/name/:tagName

 Añade una etiqueta por nombre (crea etiqueta y contacto si no existen).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | tagName| string (path)| Sí| Nombre de la etiqueta (se crea si no existe).|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/tag/name/Cliente \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [{ "id": "a1b2...", "name": "Cliente", "color": "#55efc4" }] }

### DELETE /v2/contact/:phone/tag/:tagId

 Quita una etiqueta del contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | tagId| string (path)| Sí| ID de la etiqueta.|

 Ejemplo de petición

 curl -X DELETE https://api.manycontacts.com/v2/contact/34600111222/tag/a1b2... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### POST /v2/contact/:phone/team/:teamId

 Asigna el contacto (por teléfono) a un equipo.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | teamId| string (path)| Sí| ID del equipo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/contact/34600111222/team/7c9d... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### DELETE /v2/contact/:phone/team/:teamId

 Quita el contacto (por teléfono) de un equipo.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | teamId| string (path)| Sí| ID del equipo.|

 Ejemplo de petición

 curl -X DELETE https://api.manycontacts.com/v2/contact/34600111222/team/7c9d... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 { "id": "8f3c...", "name": "Juan", "number": "34600111222", "tags": [] }

### GET /v2/contact/:phone/bot/init

 Lanza el primer mensaje del chatbot al contacto (por teléfono).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 Ejemplo de petición

 curl https://api.manycontacts.com/v2/contact/34600111222/bot/init \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

### PUT /v2/contact/:phone/stage/:column

 Mueve el contacto a la etapa del embudo indicada por su orden.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | phone| string (path)| Sí| Teléfono del contacto en formato internacional (solo dígitos), en la ruta.|

 | column| integer (path)| Sí| Orden (índice) de la etapa del embudo por defecto, empezando en 0.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v2/contact/34600111222/stage/2 \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

## Etiquetas

 Crea y gestiona las etiquetas de tu organización.

### GET /v1/tags

 Lista las etiquetas (filtro opcional por nombre).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | filter| string (query)| No| Filtra las etiquetas por nombre (búsqueda parcial, sin distinción de mayúsculas).|

 Ejemplo de petición

 curl "https://api.manycontacts.com/v1/tags?filter=cliente" \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 [
 { "id": "a1b2...", "name": "Cliente", "color": "#55efc4", "createdAt": "2026-07-09T13:00:00.000Z" }
]

### POST /v1/tag

 Crea una etiqueta (name obligatorio, color opcional).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | name| string| Sí| Nombre de la etiqueta.|

 | color| string| No| Color en formato hexadecimal (máx. 7 caracteres). Si se omite, se asigna uno al azar.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/tag \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "name": "VIP", "color": "#e84393" }'
 Ejemplo de respuesta

 { "id": "c3d4...", "name": "VIP", "color": "#e84393", "createdAt": "2026-07-09T13:00:00.000Z" }

### PUT /v1/tag/:id

 Actualiza el nombre o color de una etiqueta.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID de la etiqueta.|

 | name| string| No| Nombre de la etiqueta.|

 | color| string| No| Color en formato hexadecimal (máx. 7 caracteres). Si se omite, se asigna uno al azar.|

 Ejemplo de petición

 curl -X PUT https://api.manycontacts.com/v1/tag/c3d4... \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "name": "VIP Gold", "color": "#fdcb6e" }'
 Ejemplo de respuesta

 { "id": "c3d4...", "name": "VIP Gold", "color": "#fdcb6e", "createdAt": "2026-07-09T13:00:00.000Z" }

### DELETE /v1/tag/:id

 Elimina una etiqueta.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | id| string (path)| Sí| ID de la etiqueta.|

 Ejemplo de petición

 curl -X DELETE https://api.manycontacts.com/v1/tag/c3d4... \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 HTTP/1.1 200 OK
 Devuelve 200 sin cuerpo cuando la operación es correcta.

## Equipos

 Consulta los equipos de tu organización y sus miembros.

### GET /v1/teams

 Lista los equipos con sus miembros.

 Este endpoint no requiere parámetros.

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/teams \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 [
 {
 "id": "7c9d...",
 "name": "Ventas",
 "members": [
 { "id": "5d2a...", "name": "Ana" },
 { "id": "6e3b...", "name": "Luis" }
 ]
 }
]

## Plantillas (v1)

 Envía plantillas de WhatsApp aprobadas por Meta. Útiles para iniciar conversaciones fuera de la ventana de 24 horas. La v1 admite una única variable de cuerpo mediante el parámetro text.

### GET /v1/templates

 Lista las plantillas aprobadas y visibles.

 Este endpoint no requiere parámetros.

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/templates \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 [
 {
 "name": "bienvenida",
 "text": "Hola &#123;&#123;1&#125;&#125;, tu cita es el &#123;&#123;2&#125;&#125;",
 "hasImage": false,
 "hasDocument": false,
 "hasVideo": false
 }
]

### POST /v1/template/:templateName/:number

 Envía una plantilla a un número (variable de cuerpo en text).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | templateName| string (path)| Sí| Nombre exacto de la plantilla aprobada en Meta.|

 | number| string (path)| Sí| Teléfono de destino en formato internacional, en la ruta.|

 | text| string| No| Valor para la variable de cuerpo de la plantilla.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/template/bienvenida/34600111222 \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "text": "Juan" }'
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

### POST /v1/template/:templateName/:number/media

 Envía una plantilla con archivo multimedia adjunto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | templateName| string (path)| Sí| Nombre exacto de la plantilla aprobada en Meta.|

 | number| string (path)| Sí| Teléfono de destino en formato internacional, en la ruta.|

 | file| file (multipart)| Sí| Archivo a enviar (multipart/form-data).|

 | text| string| No| Valor para la variable de cuerpo de la plantilla.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v1/template/bienvenida/34600111222/media \
 -H "apikey: TU_API_KEY" \
 -F "text=Juan" \
 -F "file=@catalogo.pdf"
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

## Plantillas (v2)

 Versión mejorada del envío de plantillas: acepta variables de cabecera, de cuerpo y de botones (URL dinámicas y código de oferta) como arrays (header_variables, variables y button_variables), con o sin archivo multimedia adjunto.

### POST /v2/template/:templateName/:number

 Envía una plantilla con variables de cabecera, cuerpo y botones URL (arrays).

 | Parámetro| Tipo| Obligatorio| Descripción|

 | templateName| string (path)| Sí| Nombre exacto de la plantilla aprobada en Meta.|

 | number| string (path)| Sí| Teléfono de destino en formato internacional, en la ruta.|

 | header_variables| string[]| No| Valores para las variables de la cabecera de la plantilla (array).|

 | variables| string[]| No| Valores para las variables del cuerpo de la plantilla (array).|

 | button_variables| string[]| No| Valores de los botones URL dinámicos y de copiar oferta, en el orden de los botones. En una URL es el sufijo que sustituye la variable. En una oferta es el código (máximo 20 caracteres). Son independientes de las variables del cuerpo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/template/bienvenida/34600111222 \
 -H "apikey: TU_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{ "header_variables": ["ManyContacts"], "variables": ["Juan", "10:00"], "button_variables": ["verano", "BF26"] }'
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

### POST /v2/template/:templateName/:number/media

 Envía una plantilla v2 con archivo multimedia adjunto.

 | Parámetro| Tipo| Obligatorio| Descripción|

 | templateName| string (path)| Sí| Nombre exacto de la plantilla aprobada en Meta.|

 | number| string (path)| Sí| Teléfono de destino en formato internacional, en la ruta.|

 | file| file (multipart)| Sí| Archivo a enviar (multipart/form-data).|

 | header_variables| string[]| No| Valores para las variables de la cabecera de la plantilla (array).|

 | variables| string[]| No| Valores para las variables del cuerpo de la plantilla (array).|

 | button_variables| string[]| No| Valores de los botones URL dinámicos y de copiar oferta, en el orden de los botones. En una URL es el sufijo que sustituye la variable. En una oferta es el código (máximo 20 caracteres). Son independientes de las variables del cuerpo.|

 Ejemplo de petición

 curl -X POST https://api.manycontacts.com/v2/template/bienvenida/34600111222/media \
 -H "apikey: TU_API_KEY" \
 -F 'variables=["Juan", "10:00"]' \
 -F 'button_variables=["verano", "BF26"]' \
 -F "file=@catalogo.pdf"
 Ejemplo de respuesta

 { "id": "8f3c...", "error": null }

## Usuarios

 Consulta los usuarios (agentes) de tu organización.

### GET /v1/users

 Lista los usuarios con su id, nombre e indicador de IA.

 Este endpoint no requiere parámetros.

 Ejemplo de petición

 curl https://api.manycontacts.com/v1/users \
 -H "apikey: TU_API_KEY"
 Ejemplo de respuesta

 [
 { "id": "5d2a...", "name": "Ana", "ai": false },
 { "id": "9f8e...", "name": "Agente IA", "ai": true }
]

## Webhooks

 ManyContacts puede reenviar eventos de tu organización a una URL propia mediante peticiones POST, para que integres los eventos en tus sistemas en tiempo real.

 Configúralos en la app: Ajustes → Desarrolladores. Activa el reenvío e indica una URL HTTPS de destino.

 Cada evento se envía como un POST con un cuerpo JSON con esta forma (event, delta y el objeto contact completo):

 {
 "event": "message_new",
 "delta": {
 "contactId": "8f3c...",
 "message": { "id": "...", "text": "Hola", "type": "received", "metadata": { "time": "2026-07-09T13:00:00.000Z" } }
 },
 "contact": {
 "id": "8f3c...",
 "name": "Juan",
 "email": null,
 "open": true,
 "last_user_id": null,
 "number": "34600111222",
 "notes": null,
 "locked": false,
 "customFields": {},
 "tags": []
 }
}
 Eventos disponibles

 | event| Descripción|

 | message_new| Nuevo mensaje entrante del contacto.|

 | message_sent| Mensaje saliente enviado al contacto.|

 | mediafile_new| Nuevo archivo multimedia recibido o enviado.|

 | contact_created| Se ha creado un contacto nuevo.|

 | contact_update| Se ha actualizado el contacto (por ejemplo, sus notas).|

 | contact_update_custom_fields| Se han actualizado los campos personalizados del contacto.|

 | contact_update_tag_added| Se ha añadido una etiqueta al contacto.|

 | contact_update_tag_deleted| Se ha eliminado una etiqueta del contacto.|

 | contact_ai_welcome| El agente de IA ha enviado un mensaje de bienvenida.|

 | conversation_data| Datos estructurados extraídos de la conversación por la IA.|

 | message_flow_new| Respuesta recibida de un Flow de Meta.|

 Por seguridad, si tu endpoint acumula errores de forma repetida, ManyContacts desactivará automáticamente el reenvío de webhooks.

## ¿Listo para integrar?

 Consigue tu API key en la app y empieza a construir. ¿Dudas? Escríbenos.

 Empezar gratis
 Contactar con soporte
