Your AI Connector Docs

Messages et conversations

L’API Messages vous permet d’envoyer un message à n’importe quel contact, de relire une conversation, de corriger ou de supprimer un message déjà envoyé, d’y réagir, de récupérer l’intégralité d’un fil de discussion, d’exporter une transcription et de marquer des discussions comme lues ou non lues — tout cela sans ouvrir la boîte de réception.

Tous les chemins sur cette page sont relatifs à l’URL de base https://api.youraiconnector.com/v1. Chaque requête nécessite votre clé API — consultez Authentification pour obtenir la liste complète des méthodes pour l’envoyer. Les exemples ci-dessous utilisent l’en-tête X-API-Key, avec un exemple cURL montrant également le formulaire de requête ?apiKey=.

Fonctionnement de la livraison : L’envoi d’un message n’attend pas qu’il soit arrivé à destination. L’API accepte votre message, renvoie immédiatement un identifiant de message, puis le livre en arrière-plan sur le canal du contact (WhatsApp, SMS, Instagram, etc.). Pour savoir si un message a réellement été livré ou lu, écoutez les mises à jour de statut avec les Webhooks — ne faites pas de polling. La réponse d’envoi confirme uniquement que le message a été accepté.


Envoyer un message

Il existe deux façons d’envoyer un message. Choisissez celle qui correspond à la manière dont vous identifiez déjà le contact :

  • Envoyer par ID de contact — vous connaissez déjà l’ID du contact (par exemple, vous avez créé le contact via l’API ou l’avez obtenu via un webhook). Utilisez POST /contacts/{contactId}/send-message.
  • Envoyer par identité de contact — vous connaissez le numéro de téléphone, l’identifiant Instagram, etc. du contact, mais pas son ID interne. Utilisez POST /contacts/send et laissez la plateforme trouver le bon contact.

Les deux méthodes mettent le message en file d’attente de la même manière et le livrent sur le canal utilisé par le contact. Vous ne choisissez pas le transport — la plateforme achemine les contacts WhatsApp via WhatsApp, les contacts SMS via SMS, et ainsi de suite.

Envoyer par ID de contact

POST /contacts/{contactId}/send-message

Champ Requis Description
body Oui Le texte du message à envoyer.
mediaUrl Non URL d’un fichier média (image, document, etc.) à joindre.
mediaContentType Non Type MIME du média joint, par ex. image/jpeg.
pauseBot Non true met l’IA en pause pour ce contact lors de l’envoi du message — pour une intervention humaine. Voir Mettre en pause ou reprendre l’IA.
clearIncompleteReply Non true annule une réponse du bot en cours de rédaction afin qu’elle ne reprenne pas après votre message.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
    }),
  }
);
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])

Réponse (200 OK) :

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

Envoyer par identité de contact

POST /contacts/send

Utilisez cette méthode lorsque vous ne disposez pas de l’ID interne du contact. Fournissez le body du message ainsi que soit un contact_id, soit un channel accompagné du champ d’identité correspondant à ce canal.

Champ Requis Description
body Oui Le texte du message à envoyer.
contact_id Non ID d’un contact existant. Lorsqu’il est défini, les champs d’identité ci-dessous ne sont pas nécessaires.
channel Non Canal utilisé pour l’envoi. Requis lorsque contact_id n’est pas fourni. L’un des 14 canaux d’envoi sortant : whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber.
phone_number Non Numéro de téléphone du contact au format international. Utilisé avec whatsapp, whatsapp_web et sms.
instagram_id Non ID utilisateur Instagram du contact. Utilisé avec instagram.
messenger_id Non ID utilisateur Messenger du contact. Utilisé avec messenger.
telegram_user_id Non ID utilisateur Telegram du contact. Utilisé avec telegram.
media_url Non URL d’un fichier multimédia à joindre.
media_content_type Non Type MIME du média joint, par ex. image/jpeg.

Quels canaux peuvent être résolus par identité. Seuls six des 14 acceptent un champ d’identité au lieu d’un contact_id : whatsapp, whatsapp_web et sms sont recherchés par phone_number, instagram par instagram_id, messenger par messenger_id, et telegram par telegram_user_id. Les huit autres — instagram_private, chat-widget, custom, email, line, imessage, linkedin et viber — n’ont pas d’identité publique à rechercher, donc l’envoi sur ces canaux nécessite contact_id ; passer channel seul renvoie une 400 vous indiquant que contact_id est requis.

cURL (utilisant le formulaire de requête ?apiKey=)

curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "body": "Hi! Your appointment is confirmed."
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel: "whatsapp",
    phone_number: "+31612345678",
    body: "Hi! Your appointment is confirmed.",
  }),
});
const data = await res.json();
console.log(data.message_id, data.channel);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/send",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "channel": "whatsapp",
        "phone_number": "+31612345678",
        "body": "Hi! Your appointment is confirmed.",
    },
)
data = res.json()
print(data["message_id"], data["channel"])

Réponse (201 Created) :

{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp"
}

Pourquoi un message peut être rejeté : Un contact ayant activé le mode « ne pas déranger » ou le mode privé ne peut pas recevoir de messages sortants — la requête échoue avec une erreur 422. Si aucun contact ne correspond à l’ID ou à l’identité que vous avez fourni(e), vous recevrez une erreur 404.


Lister les messages d’un contact

GET /contacts/{contactId}/messages

Renvoie les messages d’un contact, du plus récent au plus ancien, avec une pagination basée sur un curseur.

Paramètre de requête Requis Description
limit Non Taille de la page. Par défaut 50, maximum 100.
cursor Non La valeur next_cursor issue d’une réponse précédente. Renvoie les messages antérieurs au curseur.
filter Non Filtrer par type de contenu : all (par défaut), text, media ou tool_use.
direction Non Filtrer par direction : all (par défaut), inbound (reçu du contact) ou outbound (envoyé par vous).

Remarque sur le filtrage et la pagination : Les filtres filter et direction sont appliqués à chaque page après sa lecture ; une page filtrée peut donc contenir moins d’éléments que limit. Le next_cursor continue de progresser dans la conversation complète, donc continuez la pagination jusqu’à ce que next_cursor soit null.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
  `https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T10:00:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ],
  "next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}

Champs de message

Champ Description
id ID unique du message.
body Contenu textuel du message.
direction inbound (reçu du contact) ou outbound (envoyé par votre compte).
channel Canal sur lequel le message a été envoyé ou reçu (par ex. whatsapp, sms, instagram).
status État de livraison actuel, par ex. Created, sent, delivered, read, failed.
type Type de message. Les messages en texte brut ont un type null ; l’activité des outils d’assistance automatisés est marquée tool_use.
timestamp Heure ISO 8601 de création du message.
media_url URL d’un fichier multimédia joint, le cas échéant.
media_content_type Type MIME du média joint, le cas échéant.
bot_reply true lorsque le message a été généré par l’assistant IA.
score Votre évaluation du message : 1 pouce levé, -1 pouce baissé, 0 lorsqu’il n’a pas été évalué. Voir Évaluer ou marquer un message.
is_important true lorsque le message a été marqué d’une étoile.
is_deleted true lorsque le message a été supprimé. Les messages supprimés restent dans la liste mais leurs champs body et media_url sont vides.
reactions Réactions par émojis sur le message, des deux côtés. Toujours un tableau — vide s’il n’y en a pas. Chaque entrée contient emoji, from_phone_number, from_me (true lorsque la réaction est la vôtre) et reacted_at.

Lister les sessions de discussion

Une session de discussion est une fenêtre de conversation avec un contact : elle s’ouvre lorsqu’il commence à parler et se ferme lorsque la conversation est terminée. Les sessions vous permettent de diviser un long historique en conversations lisibles plutôt qu’en une liste interminable.

Sessions récentes pour tous les contacts

GET /chat-sessions/recent

Renvoie les sessions qui ont commencé au cours des X dernières heures, de la plus récente à la plus ancienne, pour chaque contact du compte.

Paramètre de requête Requis Description
hours Oui Combien d’heures remonter en arrière. Doit être un nombre entier positif.
status Non Ne renvoyer que les sessions avec ce statut : ChatSessionOpened ou ChatSessionClosed.
limit Non Nombre maximum de sessions à renvoyer. Par défaut 100, maximum 100.
includeMessages Non true ajoute un tableau messages à chaque session. Désactivé par défaut car cela alourdit considérablement la réponse.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-sessions/recent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])

Réponse (200 OK) :

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_sessions": 2,
    "sessions": [
      {
        "session_id": "session456",
        "contact_id": "contact123",
        "contact_name": "Jane Doe",
        "contact_phone": "+31612345678",
        "contact_email": "jane@example.com",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Toutes les sessions pour un contact

GET /chat-sessions/{contactId}

Renvoie toutes les sessions de discussion pour un seul contact. Mêmes paramètres status, limit et includeMessages que ci-dessus — hours ne s’applique pas ici.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Réponse (200 OK) :

{
  "success": true,
  "data": {
    "contact_id": "contact123",
    "contact_name": "Jane Doe",
    "total_sessions": 2,
    "sessions": [
      {
        "id": "session456",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Les noms des champs d’ID de session diffèrent entre les deux points de terminaison. La liste des sessions récentes l’appelle session_id (elle contient également les détails du contact, car les sessions proviennent de nombreux contacts) ; la liste par contact l’appelle id. L’une ou l’autre valeur est ce que vous transmettez en tant que {sessionId} lors de la récupération du fil complet ci-dessous.

Lorsque includeMessages=true, chaque session gagne un tableau messages dont les entrées contiennent id, body, direction, timestamp, type, channel et status.


Récupérer un fil de discussion

GET /contacts/{contactId}/chat-sessions/{sessionId}/messages

Une session de chat regroupe les messages d’un contact dans une seule fenêtre de conversation. Ce point de terminaison renvoie le fil complet d’une session unique, du plus ancien au plus récent, ainsi que les métadonnées de la session. Vous pouvez trouver les identifiants de session d’un contact via les points de terminaison des sessions de chat.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "session": {
    "id": "session456",
    "status": "ChatSessionClosed",
    "start_date_time": "2026-06-01T09:55:00.000Z",
    "end_date_time": "2026-06-01T10:20:00.000Z",
    "tag": "Booking enquiry"
  },
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T09:55:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ]
}

L’objet session rapporte status (ChatSessionOpened lorsqu’elle est active, ChatSessionClosed une fois terminée), start_date_time, end_date_time, et un tag lisible par l’homme. Le tableau messages utilise les mêmes champs de message que le point de terminaison de liste.


Modifier, supprimer et réagir aux messages

Ces points de terminaison modifient un message après son envoi. Deux d’entre eux interagissent avec le canal du contact ainsi qu’avec votre propre copie. Lisez donc l’introduction de la section avant de les configurer — ce qui est possible dépend entièrement du canal sur lequel se déroule la conversation.

Ce que chaque canal permet

Action Canaux pouvant modifier la copie du contact Délai
Modifier un message envoyé Widget de chat, WhatsApp Web, Telegram, LinkedIn Aucun pour le widget de chat, 15 minutes sur WhatsApp Web, 48 heures sur Telegram, 60 minutes sur LinkedIn
Supprimer pour tout le monde Widget de chat, WhatsApp Web, Telegram, LinkedIn 60 minutes sur LinkedIn ; les autres n’ont pas de limite publiée
Réagir avec un emoji WhatsApp Web, Telegram Aucun

Sur tous les autres canaux — l’API WhatsApp Business, SMS, Instagram, Messenger, e-mail, LINE, canaux personnalisés — une suppression retire toujours le message de votre boîte de réception, mais le contact conserve sa copie, et la modification ou la réaction est totalement impossible.

Modifier un message

POST /contacts/{contactId}/messages/{messageId}/edit

Réécrit un message que vous avez déjà envoyé, sur l’appareil du contact et dans votre copie.

Champ Requis Description
body Oui Le nouveau texte du message. Ne doit pas être vide et peut contenir au maximum 4096 caractères.

Contrairement à la suppression, cette opération échoue bruyamment lorsque le canal refuse : vous obtenez une 409 et votre copie reste exactement telle que le contact l’a, car afficher une modification qu’il n’a jamais reçue créerait un décalage entre les deux parties. Le champ edit_reason vous indique pourquoi — la fenêtre de modification du canal est fermée, le canal est déconnecté ou une autre erreur est survenue.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Sorry - I meant Thursday at 3pm." }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
  }
);
const data = await res.json();
console.log(data.edited, data.edit_reason);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "edited": true,
  "edit_reason": "edit_dispatched"
}

Si le canal n’accepte pas la modification, vous obtenez une 409 à la place, et rien n’est modifié :

{
  "success": false,
  "error": "The message could not be edited",
  "edit_reason": "channel_disconnected"
}

Un message déjà supprimé, un canal qui ne permet aucune modification et un message trop ancien pour son canal renvoient tous une 400 — la requête n’atteint jamais le canal.

Supprimer un message

DELETE /contacts/{contactId}/messages/{messageId}

Supprime le message de votre conversation et, lorsque le canal le permet, retire également la copie du contact. Aucun corps de requête.

Ceci répond toujours 200 lorsque le message existait, même si la copie du contact n’a pas pu être retirée — votre copie est supprimée, donc une erreur serait trompeuse. Lisez les trois champs de la réponse pour indiquer à l’utilisateur ce qui s’est réellement passé :

Champ Description
revoke_supported Indique si ce canal peut retirer des messages.
revoked Indique si la copie sur l’appareil du contact a été supprimée.
revoke_reason Pourquoi elle n’a pas été supprimée, lorsque revoked est false — par exemple revoke_window_closed ou already_deleted.

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "revoke_supported": true,
  "revoked": true,
  "revoke_reason": "revoke_dispatched"
}

Les messages supprimés ne sont pas retirés de l’historique de la conversation. Ils restent dans GET /contacts/{contactId}/messages avec is_deleted: true ainsi qu’un body et un media_url vides.

Supprimer plusieurs messages à la fois

POST /contacts/{contactId}/messages/bulk-delete

Efface un lot de messages de votre côté uniquement. Le corps et les pièces jointes sont vidés, mais rien n’est rétracté sur l’appareil du contact — pour également retirer un message, supprimez-le un par un avec le point de terminaison pour message unique ci-dessus.

Champ Requis Description
message_ids Oui Un tableau non vide d’identifiants de message, jusqu’à 500 par requête. messageIds est accepté comme alias.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message_ids": ["msg_1", "msg_2"] }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
  }
);
console.log((await res.json()).deleted);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "deleted": 2
}

Réagir à un message

POST /contacts/{contactId}/messages/{messageId}/react

Ajoute votre propre réaction emoji sur un message, ou la retire en envoyant une chaîne vide. Les réactions du contact ne sont jamais modifiées.

Champ Requis Description
emoji Oui L’emoji avec lequel réagir, ou "" pour supprimer votre réaction. Doit être une chaîne unique sans espaces, de 16 caractères maximum.

Tout comme pour la modification, cela échoue plutôt que d’afficher une réaction que le contact n’a jamais reçue, et l’échec vous indique si une nouvelle tentative en vaut la peine :

  • 422 — il ne pourra jamais être délivré dans cette conversation : le canal ne prend pas en charge les réactions, le message n’a pas d’identifiant côté canal, ou l’emoji est en dehors de l’ensemble autorisé par ce canal.
  • 409 — le canal était momentanément inaccessible. Une nouvelle tentative peut fonctionner.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emoji": "👍" }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emoji: "👍" }),
  }
);
const data = await res.json();
console.log(data.reactions);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"emoji": "👍"},
)
print(res.json()["reactions"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "reaction_supported": true,
  "reaction_reason": "reaction_dispatched",
  "reactions": [
    {
      "emoji": "👍",
      "from_phone_number": "+31612345678",
      "from_me": true,
      "reacted_at": "2026-06-01T10:05:00.000Z"
    }
  ]
}

Le tableau reactions est l’ensemble complet des réactions présentes sur le message, les vôtres et celles du contact. Sur un 409 ou un 422, il est renvoyé inchangé, de sorte qu’un client effectuant le rendu directement à partir de celui-ci n’affiche jamais une réaction qui n’a pas été délivrée.

Évaluer ou marquer un message

PATCH /contacts/{contactId}/messages/{messageId}

Évalue un message avec un pouce levé ou baissé et/ou le marque comme important. Il s’agit d’une gestion interne de votre côté uniquement — rien n’est envoyé au contact.

Champ Requis Description
score Non 1 pouce levé, -1 pouce baissé, 0 efface l’évaluation.
is_important Non true ajoute une étoile au message, false retire l’étoile. Doit être un booléen réel, pas la chaîne "true".

Envoyez au moins l’un des deux, sinon vous recevrez une 400. Seul ce que vous envoyez est écrit, donc ajouter une étoile à un message n’efface jamais son évaluation et vice versa — et la réponse ne renvoie que les champs que vous avez envoyés.

cURL

curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "score": 1, "is_important": true }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
  method: "PATCH",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ score: 1, is_important: true }),
});

Python

import requests

requests.patch(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"score": 1, "is_important": True},
)

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "score": 1,
  "is_important": true
}

Marquer les messages comme lus

Vous pouvez supprimer l’état non lu soit pour des messages spécifiques, soit pour l’ensemble de la conversation.

Marquer des messages spécifiques comme lus

POST /contacts/{contactId}/messages/mark-read

Transmettez les identifiants des messages à marquer comme lus.

Champ Requis Description
message_ids Oui Un tableau non vide d’identifiants de message (jusqu’à 500 par requête).

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
    }),
  }
);
const data = await res.json();
console.log(data.marked_read);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123",
  "marked_read": 2
}

Marquer l’intégralité du chat comme lu

POST /contacts/{contactId}/mark-read

Supprime le badge de non-lu pour toute la conversation du contact dans la boîte de réception. Aucun corps de requête n’est requis.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123"
}

Marquer toute la conversation comme non lue

POST /contacts/{contactId}/mark-unread

Remet le badge de non lu sur la conversation — pratique lorsqu’un membre de votre équipe a ouvert une discussion mais la transmet à quelqu’un d’autre. Aucun corps de requête n’est requis.

Il s’agit d’un indicateur propre à la boîte de réception : il ne modifie pas la date de dernière lecture de la conversation, donc aucun accusé de lecture n’est envoyé au contact sur les canaux qui les prennent en charge.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
  -H "X-API-Key: YOUR_API_KEY"

Réponse (200 OK) :

{
  "success": true,
  "contact_id": "contact123"
}

Exporter une conversation

Les exportations vous fournissent une conversation entière sous forme de transcription lisible, plutôt que de parcourir les messages page par page. Chaque point de terminaison d’exportation accepte un filter de all (par défaut), text, media ou tool_use, correspondant au filtre de la liste des messages.

Exporter la discussion d’un contact

GET /chat-exports/{contactId}

Paramètre de requête Requis Description
format Non txt (par défaut) renvoie un lien de téléchargement vers une transcription en texte brut. json renvoie les messages sous forme de données structurées dans la réponse.
filter Non all (par défaut), text, media ou tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
  -H "X-API-Key: YOUR_API_KEY"

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-exports/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"format": "json"},
)
print(res.json()["data"]["messages"])

Réponse avec format=json (200 OK) :

{
  "success": true,
  "data": {
    "contact": {
      "id": "contact123",
      "name": "Jane Doe",
      "phone": "+31612345678",
      "email": "jane@example.com"
    },
    "messages": [
      {
        "body": "Hi! I have a question about my order.",
        "direction": "inbound",
        "timestamp": "2026-06-01T09:55:00.000Z",
        "type": "text",
        "media_url": null,
        "media_content_type": null,
        "name": null,
        "args": null
      }
    ]
  }
}

Avec format=txt (la valeur par défaut), data est plutôt un lien de téléchargement vers le fichier de transcription généré :

{
  "success": true,
  "data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}

Le lien de téléchargement est éphémère. Récupérez le fichier dès que vous obtenez le lien plutôt que de le stocker — demandez une nouvelle exportation lorsque vous avez à nouveau besoin de la transcription.

Exporter toutes les conversations récentes

GET /chat-exports/recent

Exporte les conversations de tous les contacts ayant été actifs au cours des X dernières heures, en un seul appel.

Paramètre de requête Requis Description
hours Oui Nombre d’heures d’activité à prendre en compte. Doit être un nombre entier positif.
format Non json (par défaut) renvoie une entrée par contact. txt renvoie un fichier texte unique téléchargeable contenant toutes les conversations.
limit Non Nombre maximum de contacts à exporter. Par défaut 50, maximum 100.
filter Non all (par défaut), text, media ou tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"

Réponse (200 OK) :

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_contacts": 2,
    "exports": [
      {
        "contactId": "contact123",
        "contactName": "Jane Doe",
        "phoneNumber": "+31612345678",
        "email": "jane@example.com",
        "messageCount": 12,
        "chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
      }
    ]
  }
}

Avec format=txt, la réponse est le fichier texte lui-même, envoyé en tant que téléchargement plutôt qu’au format JSON.

Cet appel unique extrait l’historique complet de chaque contact correspondant, veillez donc à ce que hours et limit restent raisonnables sur les comptes très actifs.

Envoyer une transcription par e-mail au contact

POST /chat-exports/{contactId}/email

Envoie au contact sa propre transcription de conversation par e-mail — le flux « m’envoyer cette discussion par e-mail », piloté depuis votre propre système.

Champ Requis Description
recipient_email Non Où l’envoyer. Par défaut, l’adresse e-mail enregistrée du contact.
via Non auto (par défaut) choisit le meilleur itinéraire, transactional l’envoie en tant qu’e-mail système, email_channel l’envoie depuis votre canal e-mail connecté.
note Non Une courte ligne de votre part affichée au-dessus de la transcription. Jusqu’à 1000 caractères.

cURL

curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Here is a copy of our chat, as promised." }'

Réponse (200 OK) :

{
  "success": true,
  "data": {
    "via": "transactional",
    "recipientEmail": "jane@example.com",
    "messageCount": 42,
    "omittedCount": 0
  }
}

omittedCount vous indique combien des messages les plus anciens ont été omis pour conserver une longueur raisonnable à l’e-mail. Un 200 signifie que la transcription a été générée et mise en file d’attente pour l’envoi, et non qu’elle est déjà arrivée dans la boîte de réception.


Mettre en pause ou reprendre l’IA pour un contact

PUT /contacts/{contactId}

Définissez is_bot_active sur false pour empêcher l’IA de répondre à un contact, et remettez-le sur true pour lui rendre la conversation. C’est l’interrupteur de prise en main que vous souhaitez utiliser lorsqu’un humain intervient dans une conversation : les messages sortants que vous envoyez via l’API sont toujours délivrés pendant que le bot est en pause.

cURL

curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_bot_active": false }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ is_bot_active: false }),
});

Python

import requests

requests.put(
    "https://api.youraiconnector.com/v1/contacts/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_bot_active": False},
)

Réponse

{
  "success": true,
  "contact_id": "contact123"
}

Mise en pause lors d’une réponse

Si un humain prend le relais en envoyant une réponse, vous pouvez mettre le bot en pause dans la même requête au lieu d’effectuer un second appel. POST /contacts/{contactId}/send-message accepte deux options facultatives :

Champ Description
pauseBot true met l’IA en pause pour ce contact lors de l’envoi du message.
clearIncompleteReply true annule une réponse du bot en cours de rédaction afin qu’elle ne reprenne pas par la suite.
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi, Sarah here - taking over from the assistant.",
    "pauseBot": true,
    "clearIncompleteReply": true
  }'

La réponse inclut "botPaused": true lorsque la pause a été appliquée.

Marquer un contact comme privé avec POST /contacts/bulk-flag met également le bot en pause pour lui. Voir Contacts pour la liste complète des champs.


Créer votre propre boîte de réception

Tout ce dont une boîte de réception a besoin se trouve sur cette page et dans Contacts :

Ce dont vous avez besoin Point de terminaison
Lister les conversations GET /contacts
Lire une conversation GET /contacts/{contactId}/messages
Lister les sessions de chat d’un contact GET /chat-sessions/{contactId}
Voir ce qui est arrivé récemment GET /chat-sessions/recent
Lire une session de chat GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Envoyer une réponse manuelle POST /contacts/{contactId}/send-message
Corriger une réponse que vous venez d’envoyer POST /contacts/{contactId}/messages/{messageId}/edit
Supprimer un message DELETE /contacts/{contactId}/messages/{messageId}
Effacer plusieurs messages POST /contacts/{contactId}/messages/bulk-delete
Réagir avec un emoji POST /contacts/{contactId}/messages/{messageId}/react
Noter ou marquer un message PATCH /contacts/{contactId}/messages/{messageId}
Marquer comme lu POST /contacts/{contactId}/mark-read
Rendre une discussion à l’équipe POST /contacts/{contactId}/mark-unread
Exporter une transcription GET /chat-exports/{contactId}
Suspendre ou reprendre l’IA PUT /contacts/{contactId} avec is_bot_active

Pour des mises à jour en temps réel, abonnez-vous aux événements New Message, Replies, Human Alerted et Chat Concluded avec les Webhooks plutôt que d’interroger cette API de manière répétée.


Erreurs de l’API Messages

Les points de terminaison de message renvoient l’enveloppe d’erreur standard :

{
  "success": false,
  "error": "Contact not found"
}
Statut Quand cela se produit sur un point de terminaison de message
400 Un champ requis est manquant ou un paramètre est invalide (mauvais limit, hours, filter, direction, status, un tableau message_ids vide ou de plus de 500 éléments, un cursor invalide, une modification body vide ou trop longue, un score en dehors de -1/0/1, ou un emoji avec des espaces ou plus de 16 caractères). Également renvoyé lorsqu’un message ne peut pas être modifié du tout — il a été supprimé, son canal ne permet pas la modification, ou il est en dehors de la fenêtre de modification de ce canal.
404 Le contact, la session de chat ou l’un des identifiants de message fournis n’a pas été trouvé.
409 Le canal n’accepte pas la modification pour le moment. Rien n’a été écrit : lors d’une modification, edit_reason explique pourquoi ; lors d’une réaction, le canal était momentanément inaccessible et une nouvelle tentative peut fonctionner.
422 Le contact ne peut pas recevoir de messages sortants (ne pas déranger, privé ou canal non pris en charge), ou une réaction ne peut jamais être délivrée sur cette conversation (reaction_reason indique lequel).

Les codes partagés que chaque point de terminaison peut renvoyer — 401, 403 (votre forfait n’inclut pas l’accès à l’API), 429 (limite de débit) et 500 — sont répertoriés avec des conseils de nouvelle tentative dans Erreurs et pagination.


Étapes suivantes

  • Webhooks — recevez des mises à jour sur le statut de livraison au lieu d’interroger le serveur.
  • Contacts — créez et recherchez les contacts auxquels vous envoyez des messages.
  • Rendez-vous — réservez et gérez les rendez-vous de vos contacts.