WhatSMS/API Docs
Swagger →Empezar gratis
IntroducciónAutenticaciónErroresTickets↳ MensajesContactosCampañasAgentes IAWebhooksLímites de tarifaSDKs y n8n
⚡ Swagger interactivo

Introducción

La API REST de WhatSMS permite enviar mensajes, gestionar contactos, tickets y campañas, y escuchar eventos en tiempo real mediante webhooks. Todas las solicitudes se autentican por API Key y se aíslan por tenant.

v2

URL base

https://api.whatsms.pt/api/v2

CRUD completo, paginación estructurada, soporte de medios y rate limiting por API Key.

🔑

Clave API por inquilino

Cada cuenta tiene su propia API Key. Crea y revoca en Ajustes → Integraciones → API Keys.

🔒

HTTPS obligatorio

Todas las solicitudes deben usar HTTPS. Las solicitudes HTTP se rechazan automáticamente.

🇪🇺

GDPR nativo

Los datos permanecen en servidores europeos. Cumplimiento RGPD nativo, sin enviar datos fuera de la UE.

Autenticación

Todas las solicitudes requieren el header Authorization con la API Key en formato Bearer. Obtén tu API Key en Ajustes → Integraciones → API Keys.

Header obligatorio

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Ejemplo cURL

curl -X GET https://api.whatsms.pt/api/v2/contacts \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json"

⚠️ Seguridad

Nunca expongas la API Key en código del lado del cliente ni en repositorios públicos. Usa variables de entorno en el servidor. Si una key se ve comprometida, revócala de inmediato en Ajustes → Integraciones → API Keys.

Errores

La API usa códigos HTTP estándar. El cuerpo del error sigue siempre esta estructura:

Formato de error

{ "error": "Mensagem descritiva do erro" }
CódigoSignificado
200Éxito
201Creado con éxito
400Solicitud inválida — parámetros faltantes o incorrectos
401No autenticado — API Key inválida o ausente
403Sin permiso para este recurso
404Recurso no encontrado
429Límite de tasa alcanzado — espera antes de reintentar
500Error interno del servidor

Tickets

Un ticket representa una conversación con un contacto. Agrupa mensajes, canal, estado y el agente responsable.

GET/api/v2/ticketsListar entradas

Parámetros

status·string

Filtrar por estado: abierto, pendiente, cerrado

contactId·uuid

Filtrar por contacto

pageNumber·integer

Página (por defecto: 1)

pageSize·integer

Resultados por página (por defecto: 20, máx: 100)

Respuesta

{
  "tickets": [
    {
      "id": "uuid",
      "status": "open",
      "channel": "whatsapp",
      "contact": { "id": "uuid", "name": "João Silva", "number": "351910000000" },
      "lastMessage": "Olá, preciso de ajuda",
      "createdAt": "2026-01-15T10:30:00Z"
    }
  ],
  "count": 42,
  "hasMore": true
}
GET/api/v2/tickets/:ticketIdObtener ticket por ID

Parámetros

ticketId·uuidobligatorio

ID del ticket

Respuesta

{
  "ticket": {
    "id": "uuid",
    "status": "open",
    "channel": "whatsapp",
    "contact": { "id": "uuid", "name": "João Silva", "number": "351910000000" },
    "user": { "id": "uuid", "name": "Agente" },
    "queue": { "id": "uuid", "name": "Suporte" },
    "createdAt": "2026-01-15T10:30:00Z",
    "updatedAt": "2026-01-15T11:00:00Z"
  }
}
POST/api/v2/ticketsCrear ticket

Cuerpo de la solicitud

{
  "contactId": "uuid",         // obrigatório
  "status": "open",            // open | pending | closed
  "channel": "whatsapp",       // whatsapp | sms | telegram
  "whatsappId": "uuid",        // canal WhatsApp a usar
  "queueId": "uuid",           // fila/departamento
  "userId": "uuid"             // agente responsável
}

Respuesta

{
  "ticket": {
    "id": "uuid",
    "status": "open",
    "channel": "whatsapp",
    "createdAt": "2026-01-15T10:30:00Z"
  }
}
PUT/api/v2/tickets/:ticketIdActualizar ticket

Parámetros

ticketId·uuidobligatorio

ID del ticket

Cuerpo de la solicitud

{
  "status": "closed",          // open | pending | closed
  "userId": "uuid",            // reatribuir agente
  "queueId": "uuid"            // mover para fila
}

Respuesta

{
  "ticket": { "id": "uuid", "status": "closed", "updatedAt": "2026-01-15T12:00:00Z" }
}

Mensajes de un ticket

Los mensajes están anidados bajo el ticket. Para enviar un mensaje, usa POST /tickets/:id/messages.

GET/api/v2/tickets/:ticketId/messagesListar mensajes del ticket

Parámetros

ticketId·uuidobligatorio

ID del ticket

pageNumber·integer

Página (por defecto: 1)

pageSize·integer

Resultados por página (por defecto: 20)

Respuesta

{
  "messages": [
    {
      "id": "uuid",
      "body": "Olá, preciso de ajuda",
      "fromMe": false,
      "mediaType": null,
      "mediaUrl": null,
      "ack": 3,
      "createdAt": "2026-01-15T10:30:00Z"
    }
  ],
  "count": 15,
  "hasMore": false
}
POST/api/v2/tickets/:ticketId/messages60 req/min por API KeyEnviar mensaje

Parámetros

ticketId·uuidobligatorio

ID del ticket

Cuerpo de la solicitud

{
  "body": "Olá! Como posso ajudar?",  // obrigatório (texto ou caption)
  "mediaUrl": "https://...",           // URL de imagem/documento/áudio
  "mediaType": "image",               // image | document | audio | video
  "quotedMsgId": "uuid"               // responder a mensagem específica
}

Respuesta

{
  "message": {
    "id": "uuid",
    "body": "Olá! Como posso ajudar?",
    "fromMe": true,
    "ack": 1,
    "createdAt": "2026-01-15T10:31:00Z"
  }
}

Contactos

Gestión completa de contactos. Un contacto puede tener varios tickets en varios canales.

GET/api/v2/contactsListar contactos

Parámetros

searchParam·string

Buscar por nombre, número o email

pageNumber·integer

Página (por defecto: 1)

pageSize·integer

Resultados por página (por defecto: 20)

Respuesta

{
  "contacts": [
    {
      "id": "uuid",
      "name": "João Silva",
      "number": "351910000000",
      "email": "joao@exemplo.pt",
      "profilePicUrl": "https://...",
      "isGroup": false,
      "createdAt": "2026-01-10T09:00:00Z"
    }
  ],
  "count": 150,
  "hasMore": true
}
GET/api/v2/contacts/:contactIdObtener contacto por ID

Parámetros

contactId·uuidobligatorio

ID del contacto

Respuesta

{
  "contact": {
    "id": "uuid",
    "name": "João Silva",
    "number": "351910000000",
    "email": "joao@exemplo.pt",
    "extraInfo": [{ "name": "NIF", "value": "123456789" }],
    "createdAt": "2026-01-10T09:00:00Z"
  }
}
POST/api/v2/contactsCrear contacto

Cuerpo de la solicitud

{
  "name": "João Silva",           // obrigatório
  "number": "351910000000",       // obrigatório
  "email": "joao@exemplo.pt",
  "profilePicUrl": "https://...",
  "extraInfo": [
    { "name": "NIF", "value": "123456789" }
  ]
}

Respuesta

{
  "contact": {
    "id": "uuid",
    "name": "João Silva",
    "number": "351910000000",
    "createdAt": "2026-01-15T10:00:00Z"
  }
}
PUT/api/v2/contacts/:contactIdActualizar contacto

Parámetros

contactId·uuidobligatorio

ID del contacto

Cuerpo de la solicitud

{
  "name": "João M. Silva",
  "email": "joao.novo@exemplo.pt",
  "extraInfo": [{ "name": "Empresa", "value": "Acme Lda" }]
}

Respuesta

{
  "contact": { "id": "uuid", "name": "João M. Silva", "updatedAt": "2026-01-15T11:00:00Z" }
}

Campañas

Envío masivo a grupos de contactos mediante WhatsApp o SMS, con programación y control de estado.

⚠️ Las campañas están sujetas a las políticas de uso aceptable de WhatsApp Business. El envío masivo no autorizado puede provocar el bloqueo del número.
GET/api/v2/campaignsListar campañas

Parámetros

status·string

pendiente | en ejecución | finalizado | cancelado

pageNumber·integer

Página (por defecto: 1)

Respuesta

{
  "campaigns": [
    {
      "id": "uuid",
      "name": "Promoção Verão 2026",
      "status": "finished",
      "scheduledAt": "2026-06-01T09:00:00Z",
      "sentCount": 342,
      "failedCount": 3,
      "createdAt": "2026-05-20T10:00:00Z"
    }
  ],
  "count": 8,
  "hasMore": false
}
POST/api/v2/campaignsCrear campaña

Cuerpo de la solicitud

{
  "name": "Promoção Verão 2026",  // obrigatório
  "message": "Olá {{name}}! ...", // obrigatório (suporta {{name}}, {{number}})
  "whatsappId": "uuid",           // canal a usar
  "contactGroupId": "uuid",       // grupo de contactos alvo
  "scheduledAt": "2026-06-01T09:00:00Z"  // null = envio imediato
}

Respuesta

{
  "campaign": {
    "id": "uuid",
    "name": "Promoção Verão 2026",
    "status": "pending",
    "createdAt": "2026-05-20T10:00:00Z"
  }
}

Agentes IA

Los agentes de IA responden automáticamente a los tickets usando LLMs (Cortecs Sovereign Cloud — conformidad con el EU AI Act). Pueden usar herramientas como KiviCare, calendario, CRM y base de conocimiento.

GET/api/v2/ai-agentsListar agentes de IA

Sin parámetros obligatorios.

Respuesta

{
  "agents": [
    {
      "id": "uuid",
      "name": "Maria — Assistente FamilyClinic",
      "model": "cortecs:llama-4-maverick",
      "isActive": true,
      "enabledIntegrations": ["kivicare"],
      "handoffEnabled": true,
      "createdAt": "2026-03-01T10:00:00Z"
    }
  ]
}
POST/api/v2/ai-agents/assignAsignar agente de IA a un ticket

Cuerpo de la solicitud

{
  "ticketId": "uuid",   // obrigatório
  "agentId": "uuid"     // obrigatório — null para remover agente
}

Respuesta

{
  "ticket": { "id": "uuid", "aiAgentId": "uuid", "updatedAt": "2026-01-15T10:00:00Z" }
}

Webhooks

Configura un endpoint HTTPS para recibir eventos en tiempo real. WhatSMS hace un POST con un payload JSON firmado con HMAC-SHA256.

Header de firma

X-WhatSMS-Signature: sha256=<hmac_hex>

Verifica la firma con tu webhook secret para garantizar que la solicitud proviene de WhatSMS.

Eventos disponibles

EventoDescripción
message.receivedNuevo mensaje recibido de un contacto
message.sentMensaje enviado con éxito
message.ackConfirmación de entrega/lectura (ack 1–5)
ticket.createdNuevo ticket creado
ticket.updatedTicket actualizado (estado, agente, cola)
ticket.closedTicket cerrado
contact.createdNuevo contacto creado
contact.updatedContacto actualizado
campaign.finishedCampaña finalizada

Payload de ejemplo — message.received

{
  "event": "message.received",
  "tenantId": "uuid",
  "timestamp": "2026-01-15T10:30:00Z",
  "data": {
    "message": {
      "id": "uuid",
      "body": "Olá, preciso de ajuda",
      "fromMe": false,
      "mediaType": null,
      "createdAt": "2026-01-15T10:30:00Z"
    },
    "ticket": { "id": "uuid", "status": "open" },
    "contact": { "id": "uuid", "name": "João Silva", "number": "351910000000" }
  }
}

Límites de tarifa

Los límites son por API Key y por ventana de 1 minuto. Cuando alcanzas el límite recibes un 429 con el header Retry-After en segundos.

Punto finalLímite
Todos los endpoints v2300 req/min por API Key
POST /tickets/:id/messages60 req/min por API Key
POST /campaigns10 req/min por API Key

SDKs & Integraciones

Integra WhatSMS en tu stack con el node n8n oficial o directamente vía HTTP en cualquier lenguaje.

⚡

Nodo n8n

Node nativo para n8n con trigger de webhooks y acciones de envío de mensajes. Disponible en el marketplace de n8n.

Próximamente
🔌

HTTP / REST

API REST estándar compatible con cualquier lenguaje — JavaScript, Python, PHP, Go, etc. Usa el Swagger interactivo para explorar y probar todos los endpoints.

Abrir Swagger →

Ejemplo — enviar un mensaje con fetch

const res = await fetch("https://api.whatsms.pt/api/v2/tickets/{ticketId}/messages", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_xxxxxxxxxxxx",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ body: "Olá! Como posso ajudar?" })
});

const { message } = await res.json();
console.log(message.id);

Documentación completa y prueba todos los endpoints en el Swagger interactivo.

⚡ Abrir Swagger