Aller au contenu

Conversations

Une conversation, c’est le fil entre ton agent et un lead. L’API te donne la boîte de réception (les leads avec de l’activité) et la transcription de chaque lead, en lecture seule.

Méthode Chemin Scope
GET /conversations conversations:read
GET /conversations/{leadId}/messages conversations:read

La boîte de réception : chaque lead qui a échangé au moins un message, activité la plus récente d’abord.

Terminal window
curl "https://app.whatsetter.com/api/v1/conversations?campaign_id=acme-france-1-ab12&limit=25" \
-H "Authorization: Bearer ws_live_…"
{
"data": [
{
"lead_id": "66f1a2b3c4d5e6f7a8b9c0d1",
"phone": "33612345678",
"whatsapp_id": "33612345678@c.us",
"name": "Julien",
"status": "in_progress",
"qualified": false,
"replied": true,
"campaign_id": "acme-france-1-ab12",
"messages_count": 6,
"last_message_at": "2026-09-18T16:42:05.000Z",
"last_message_direction": "inbound"
}
],
"pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c0d1" }
}

campaign_id accepte le slug de la campagne ou son id. Sans lui, les conversations des campagnes de groupe restent à part, comme dans le dashboard. last_message_direction: "inbound" signifie que le lead a parlé en dernier : c’est ton signal « à répondre ».

leadId est l’id du lead venant de /leads ou /conversations. Les messages arrivent du plus récent au plus ancien.

Terminal window
curl "https://app.whatsetter.com/api/v1/conversations/66f1a2b3c4d5e6f7a8b9c0d1/messages?limit=50" \
-H "Authorization: Bearer ws_live_…"
{
"data": [
{
"id": "66f1a2b3c4d5e6f7a8b9c0e6",
"direction": "inbound",
"text": "Oui, 14h ça me va.",
"type": "USER_MESSAGE",
"has_media": false,
"sent_at": "2026-09-18T16:42:05.000Z"
},
{
"id": "66f1a2b3c4d5e6f7a8b9c0e5",
"direction": "outbound",
"text": "On se confirme pour demain 14h ?",
"type": "MANUAL_RESPONSE",
"has_media": false,
"sent_at": "2026-09-18T16:40:10.000Z"
}
],
"pagination": { "has_more": false, "next_cursor": "66f1a2b3c4d5e6f7a8b9c0e5" }
}
Champ Signification
direction inbound quand le lead a écrit, outbound quand l’agent, un coéquipier ou l’API a écrit.
text Le texte du message, ou null pour un message qui ne contient qu’un média.
type Type d’interaction interne, par exemple USER_MESSAGE, AI_RESPONSE, LEAD_WELCOME, FOLLOWUP, MANUAL_RESPONSE. Considère les valeurs inconnues comme opaques.
has_media true quand le message portait une image, un vocal ou un document. Le média lui-même n’est jamais lié.
sent_at ISO 8601, UTC.

Les deux endpoints renvoient pagination.has_more et pagination.next_cursor. Passe cursor=<next_cursor> pour la page suivante ; limit va de 1 à 100, 25 par défaut. Un curseur qui pointe vers une ligne supprimée répond 422 validation_error avec « Invalid or expired cursor » : repars de la première page.

Pour synchroniser une boîte de réception, interroge GET /conversations et ne récupère la transcription que des leads dont last_message_at a bougé. Pour le temps réel, préfère les webhooks.

Les transcriptions contiennent des numéros de téléphone, des noms et tout ce que la personne a écrit. Traite-les comme des données personnelles : ne stocke que ce dont ton usage a besoin, respecte ta politique de conservation, et ne les montre jamais à quelqu’un qui ne pourrait pas ouvrir la boîte de réception WhatSetter. phone ne contient que des chiffres, sans le +.

HTTP code Quand
401 missing_api_key, invalid_api_key Clé absente, inconnue ou révoquée.
403 insufficient_scope La clé n’a pas conversations:read.
404 not_found Lead inconnu, ou lead d’un autre espace de travail.
422 validation_error limit hors de 1 à 100, curseur invalide ou expiré.
429 rate_limited Trop de requêtes cette minute. Respecte Retry-After.