WhatSMS/API Docs
Swagger →Commencer gratuitement
IntroductionAuthentificationErreursTickets↳ MessagesContactsCampagnesAgents IAWebhooksLimites de tauxSDKs & n8n
⚡ Swagger interactif

Introduction

L'API REST de WhatSMS permet d'envoyer des messages, de gérer les contacts, les tickets et les campagnes, et d'écouter les événements en temps réel via webhooks. Chaque requête est authentifiée par API Key et isolée par tenant.

v2

URL de base

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

CRUD complet, pagination structurée, prise en charge des médias et rate limiting par API Key.

🔑

API Key par tenant

Chaque compte possède sa propre API Key. Créez et révoquez dans Paramètres → Intégrations → API Keys.

🔒

HTTPS obligatoire

Toutes les requêtes doivent utiliser HTTPS. Les requêtes HTTP sont rejetées automatiquement.

🇪🇺

RGPD natif

Les données restent sur des serveurs européens. Conformité RGPD native, sans envoyer de données hors de l'UE.

Authentification

Chaque requête nécessite l'en-tête Authorization avec l'API Key au format Bearer. Obtenez votre API Key dans Paramètres → Intégrations → API Keys.

En-tête obligatoire

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Exemple cURL

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

⚠️ Sécurité

N'exposez jamais l'API Key dans du code côté client ou des dépôts publics. Utilisez des variables d'environnement sur le serveur. Si une key est compromise, révoquez-la immédiatement dans Paramètres → Intégrations → API Keys.

Erreurs

L'API utilise des codes HTTP standard. Le corps de l'erreur suit toujours cette structure :

Format d'erreur

{ "error": "Mensagem descritiva do erro" }
CodeSignification
200Succès
201Créé avec succès
400Requête invalide — paramètres manquants ou incorrects
401Non authentifié — API Key invalide ou manquante
403Aucune permission pour cette ressource
404Ressource introuvable
429Limite de débit atteinte — attendez avant de réessayer
500Erreur interne du serveur

Tickets

Un ticket représente une conversation avec un contact. Il regroupe les messages, le canal, l'état et l'agent responsable.

GET/api/v2/ticketsLister les tickets

Paramètres

status·string

Filtrer par état : open, pending, closed

contactId·uuid

Filtrer par contact

pageNumber·integer

Page (par défaut : 1)

pageSize·integer

Résultats par page (default: 20, max: 100)

Réponse

{
  "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/:ticketIdObtenir un ticket par ID

Paramètres

ticketId·uuidobligatoire

ID du ticket

Réponse

{
  "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/ticketsCréer un ticket

Corps de la requête

{
  "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
}

Réponse

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

Paramètres

ticketId·uuidobligatoire

ID du ticket

Corps de la requête

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

Réponse

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

Messages d'un ticket

Les messages sont imbriqués sous le ticket. Pour envoyer un message, utilisez POST /tickets/:id/messages.

GET/api/v2/tickets/:ticketId/messagesLister les messages du ticket

Paramètres

ticketId·uuidobligatoire

ID du ticket

pageNumber·integer

Page (par défaut : 1)

pageSize·integer

Résultats par page (default: 20)

Réponse

{
  "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 KeyEnvoyer un message

Paramètres

ticketId·uuidobligatoire

ID du ticket

Corps de la requête

{
  "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
}

Réponse

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

Contacts

Gestion complète des contacts. Un contact peut avoir plusieurs tickets sur plusieurs canaux.

GET/api/v2/contactsLister les contacts

Paramètres

searchParam·string

Rechercher par nom, numéro ou email

pageNumber·integer

Page (par défaut : 1)

pageSize·integer

Résultats par page (default: 20)

Réponse

{
  "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/:contactIdObtenir un contact par ID

Paramètres

contactId·uuidobligatoire

ID du contact

Réponse

{
  "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/contactsCréer un contact

Corps de la requête

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

Réponse

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

Paramètres

contactId·uuidobligatoire

ID du contact

Corps de la requête

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

Réponse

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

Campagnes

Envoi en masse à des groupes de contacts via WhatsApp ou SMS, avec planification et contrôle de l'état.

⚠️ Les campagnes sont soumises aux politiques d'utilisation acceptable de WhatsApp Business. L'envoi en masse non autorisé peut entraîner le blocage du numéro.
GET/api/v2/campaignsLister les campagnes

Paramètres

status·string

en attente | en cours | terminé | annulé

pageNumber·integer

Page (par défaut : 1)

Réponse

{
  "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/campaignsCréer une campagne

Corps de la requête

{
  "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
}

Réponse

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

Agents IA

Les agents IA répondent automatiquement aux tickets à l'aide de LLM (Cortecs Sovereign Cloud — conformité EU AI Act). Ils peuvent utiliser des outils tels que KiviCare, calendrier, CRM et base de connaissances.

GET/api/v2/ai-agentsLister les agents IA

Pas de paramètres obligatoires.

Réponse

{
  "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/assignAffecter un agent IA à un ticket

Corps de la requête

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

Réponse

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

Webhooks

Configurez un endpoint HTTPS pour recevoir des événements en temps réel. WhatSMS effectue un POST avec un payload JSON signé en HMAC-SHA256.

En-tête de signature

X-WhatSMS-Signature: sha256=<hmac_hex>

Vérifiez la signature avec votre webhook secret pour garantir que la requête provient de WhatSMS.

Événements disponibles

ÉvénementDescription
message.receivedNouveau message reçu d'un contact
message.sentMessage envoyé avec succès
message.ackAccusé de réception/lecture (ack 1–5)
ticket.createdNouveau ticket créé
ticket.updatedTicket mis à jour (état, agent, file)
ticket.closedTicket fermé
contact.createdNouveau contact créé
contact.updatedContact mis à jour
campaign.finishedCampagne terminée

Exemple de payload — 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" }
  }
}

Limites de taux

Les limites sont par API Key et par fenêtre de 1 minute. Lorsque vous atteignez la limite, vous recevez un 429 avec l'en-tête Retry-After en secondes.

Point finalLimite
Tous les endpoints v2300 req/min por API Key
POST /tickets/:id/messages60 req/min por API Key
POST /campaigns10 req/min por API Key

SDKs & Intégrations

Intégrez WhatSMS dans votre stack avec le node n8n officiel ou directement via HTTP dans n'importe quel langage.

⚡

Nœud n8n

Node natif pour n8n avec trigger de webhooks et actions d'envoi de messages. Disponible sur le marketplace n8n.

Bientôt disponible
🔌

HTTP / REST

API REST standard compatible avec tout langage — JavaScript, Python, PHP, Go, etc. Utilisez le Swagger interactif pour explorer et tester tous les endpoints.

Ouvrir Swagger →

Exemple — envoyer un message avec 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);

Documentation complète et testez tous les endpoints dans le Swagger interactif.

⚡ Ouvrir Swagger