API REST
Discutez avec vos agents intoCHAT, lisez leurs conversations, leads et sources de connaissances, synchronisez leurs contacts, et abonnez des webhooks depuis votre propre serveur ou un outil d'automatisation : clés API, scopes, limites de débit, erreurs, pagination et chaque point de terminaison avec des exemples.
L'API REST permet à votre propre serveur de communiquer avec vos agents. Envoyez un message et recevez la réponse de l'agent, lisez les conversations et les leads, créez et mettez à jour des contacts, ajoutez ou supprimez des sources de connaissances, et abonnez des webhooks aux événements d'un agent, en JSON sur HTTPS. Les applications Zapier et Make reposent sur elle. Une réponse via l'API est rédigée par le même code qu'une réponse dans le widget de chat, à partir des mêmes connaissances et réglages.
L'API est destinée aux serveurs. Elle n'envoie pas d'en-têtes CORS : une page web d'un autre site ne peut donc pas l'appeler, et votre clé API ne doit jamais apparaître dans un navigateur ni dans votre code d'intégration. Pour afficher un chat sur votre site, utilisez la balise script. Pour recevoir les événements au moment où ils se produisent, utilisez les webhooks.
Offres qui incluent l'API
L'API est incluse dans les offres Starter, Pro et Enterprise. Avec l'offre Free, vous ne pouvez pas créer de clés.
Si un compte repasse à l'offre Free, ses clés restent dans la liste, mais chaque requête reçoit une erreur 403 avec le code plan_required. Elles fonctionnent de nouveau dès que le compte est sur Starter ou une offre supérieure.
Chaque réponse qu'un agent rédige via l'API compte comme un message de votre offre, exactement comme une réponse dans le widget, et compte dans le plafond mensuel de messages de l'agent si vous en avez défini un. Lire des données, et ajouter ou supprimer des sources, ne consomme aucun message. Voir Ce qui compte comme message.
Créer une clé API
- Dans la barre latérale, sous Settings, cliquez sur API keys.
- Sous Create a key, donnez à la clé un Name que vous reconnaîtrez plus tard, par exemple
CRM sync. - Sous Access, gardez Every scope, including ones added later, ou choisissez Only the scopes I choose et cochez ceux dont cette clé a besoin. Voir Scopes.
- Cliquez sur Create key.
- Cliquez sur Copy, conservez la clé là où votre serveur peut la lire, par exemple dans une variable d'environnement, puis cliquez sur I've saved it.
Une clé se compose de ic_live_ suivi de 32 lettres et chiffres. Elle ne s'affiche qu'une seule fois : intoCHAT n'en conserve qu'une empreinte, si bien que personne ne peut vous la montrer de nouveau. Si vous la perdez, révoquez-la et créez-en une nouvelle.
Une clé appartient au compte, pas à la personne qui l'a créée. Elle fonctionne pour tous les agents du compte, dans la limite de ses scopes, et continue de fonctionner si cette personne quitte l'équipe. Un compte peut avoir jusqu'à 20 clés actives.
Seuls le propriétaire du compte et les admins peuvent créer et révoquer des clés. Les editors et les viewers voient la liste des clés, avec uniquement leurs premiers caractères. Voir Membres de l'équipe et rôles.
La liste des clés
Chaque clé affiche son nom, ses premiers caractères (par exemple ic_live_3f9A…), ses scopes, sa date de création et sa dernière utilisation. Last used est mis à jour au plus une fois par minute.
Révoquer une clé
Cliquez sur Revoke à côté de la clé et confirmez. La clé cesse de fonctionner dès sa requête suivante, et cette action est irréversible. Révoquez une clé dès que vous pensez que quelqu'un d'autre pourrait la connaître.
Révoquer une clé supprime aussi les webhooks qu'elle a abonnés, par exemple pour Zapier ou Make, avec leur historique d'envois : rien d'autre ne pourrait les retirer. Les webhooks que vous avez ajoutés dans l'onglet Leads ne sont pas concernés.
Authentification
Envoyez la clé dans l'en-tête Authorization de chaque requête :
curl https://www.intochat.ai/api/v1/agents \
-H "Authorization: Bearer ic_live_YOUR_KEY"
Tous les points de terminaison se trouvent sous https://www.intochat.ai/api/v1. Les requêtes avec un corps envoient du JSON avec Content-Type: application/json, et chaque réponse est en JSON, sauf une réponse de chat en streaming. L'API n'utilise ni cookies ni session de connexion : la clé seule détermine ce qu'une requête peut faire.
Une clé absente, mal formée, inconnue ou révoquée reçoit une erreur 401 avec le code unauthorized.
Scopes
Un scope permet à une clé d'utiliser un groupe de points de terminaison. Une clé créée avec Every scope, including ones added later peut utiliser tous les points de terminaison, y compris ceux ajoutés à l'avenir.
| Scope | Autorise |
|---|---|
agents:read | Lister les agents et obtenir un agent |
chat | Envoyer un message à un agent. Chaque réponse compte comme un message de votre offre. |
conversations:read | Lister les conversations et obtenir une conversation avec sa transcription |
leads:read | Lister les leads, lister les contacts et obtenir un contact, ainsi que les événements de lead, de formulaire, de réservation et de retour de Lister les événements et Obtenir des exemples d'événements |
contacts:write | Créer ou mettre à jour un contact, modifier un contact et supprimer un contact |
sources:read | Lister les sources |
sources:write | Ajouter une source et supprimer une source, ce qui lance aussi l'entraînement |
webhooks:write | Abonner un webhook et désabonner un webhook |
conversations:read couvre aussi les événements de transfert, de chat en direct et de nouvelle conversation de Lister les événements.
Une requête vers un point de terminaison pour lequel la clé n'a pas de scope reçoit une erreur 403 avec le code insufficient_scope. Pour changer les scopes d'une clé, créez une nouvelle clé et révoquez l'ancienne.
Limites de débit
Chaque clé peut effectuer 60 requêtes par minute, tous points de terminaison confondus. Chaque réponse qui a passé la vérification de la clé porte ces en-têtes :
| En-tête | Valeur |
|---|---|
X-RateLimit-Limit | 60 |
X-RateLimit-Remaining | Les requêtes restantes dans la minute en cours |
X-RateLimit-Reset | La fin de la minute, en secondes Unix |
Au-delà de la limite, la requête reçoit une erreur 429 avec le code rate_limited et un en-tête Retry-After indiquant le nombre de secondes à attendre.
Le chat a deux limites supplémentaires qui ne dépendent pas de la clé : les messages de l'offre, et un agent répond à 1 000 messages par heure au maximum, widget et API confondus. Au-delà, une requête de chat reçoit une erreur 429 avec le code agent_busy.
Erreurs
Toutes les erreurs ont la même forme :
{
"error": {
"code": "insufficient_scope",
"message": "This API key doesn't have the \"chat\" scope."
}
}
Utilisez code dans votre code ; message l'explique à une personne et peut changer.
| Statut | Code | Signification |
|---|---|---|
400 | invalid_request | Il manque quelque chose à la requête ou une valeur est incorrecte. Le message précise laquelle. |
401 | unauthorized | Aucune clé, ou la clé est mal formée, inconnue ou révoquée. |
403 | insufficient_scope | La clé n'a pas le scope dont ce point de terminaison a besoin. |
403 | plan_required | Le compte est sur l'offre Free. L'API est incluse à partir de Starter. |
403 | message_limit_reached | Le compte a utilisé tous les messages que son offre inclut pour cette période. |
403 | agent_cap_reached | L'agent a atteint le plafond mensuel de messages défini sous Share, Limits and access. |
403 | agent_private | L'agent est privé : il ne répond donc que dans le tableau de bord. Voir Agents privés. |
403 | character_limit_exceeded | Une nouvelle source ferait dépasser à l'agent les caractères d'entraînement de son offre. |
403 | contact_limit_reached | Un nouveau contact ferait dépasser à l'agent les contacts par agent de son offre. |
404 | not_found | Aucun agent, aucune conversation, aucune source, aucun contact ou aucun webhook de ce type dans ce compte. |
409 | conflict | Un autre contact de l'agent a déjà cet identifiant externe ou cet e-mail. |
429 | rate_limited | La clé a effectué plus de 60 requêtes au cours de cette minute. |
429 | agent_busy | L'agent répond à trop de messages en ce moment. |
500 | internal_error | Un problème est survenu de notre côté. Réessayez. |
504 | timeout | L'agent a mis trop de temps à répondre. |
Un agent, une conversation ou une source qui appartient à un autre compte reçoit 404, comme un élément qui n'existe pas.
Pagination
Lister les conversations et lister les leads renvoient une page à la fois, les plus récents en premier. Ces points de terminaison acceptent ces paramètres de requête :
| Paramètre | Contenu |
|---|---|
limit | Éléments par page, de 1 à 100. La valeur par défaut est 20. |
cursor | Le nextCursor de la page précédente, pour obtenir la suivante. |
since | Une heure ISO 8601, par exemple 2026-10-01T00:00:00Z. Seuls les éléments ayant une activité à partir de ce moment sont renvoyés : une conversation avec un message depuis, ou un lead enregistré ou envoyé de nouveau depuis. |
Une page se présente ainsi :
{
"data": [ ],
"hasMore": true,
"nextCursor": "MjAyNi0xMC0wNFQwOTowMDowMC4wMDBafGNsdjEyMw"
}
Demandez la page suivante avec ?cursor= et cette valeur, en gardant les mêmes limit et since, jusqu'à ce que hasMore vaille false et nextCursor vaille null. L'ordre est fixé par la date de création : une nouvelle activité pendant que vous parcourez les pages ne fait donc ni apparaître un élément deux fois ni disparaître un élément. Pour synchroniser régulièrement, enregistrez l'heure à laquelle vous avez lancé la dernière synchronisation et transmettez-la comme since la fois suivante.
Lister les agents
GET /api/v1/agents · scope agents:read
Tous les agents du compte, les plus récents en premier.
curl https://www.intochat.ai/api/v1/agents \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "AGENT_ID",
"name": "Acme Assistant",
"private": false,
"status": "trained",
"trainedAt": "2026-10-02T09:00:00.000Z",
"characters": 48210,
"counts": { "conversations": 312, "messages": 2240, "leads": 41, "sources": 18 },
"createdAt": "2026-09-01T09:00:00.000Z",
"updatedAt": "2026-10-02T09:00:00.000Z"
}
]
}
status vaut untrained, training, trained ou error (le dernier entraînement a échoué). characters indique combien de caractères d'entraînement utilisent les sources entraînées de l'agent.
Obtenir un agent
GET /api/v1/agents/{agentId} · scope agents:read
Un agent, dans data, avec les mêmes champs que dans Lister les agents.
Envoyer un message
POST /api/v1/agents/{agentId}/chat · scope chat
Envoie un message à l'agent et renvoie sa réponse. L'agent répond comme dans le widget : à partir de ses connaissances et de ses instructions, avec vos actions API, boutons personnalisés, formulaires de chat, la réservation, le transfert par e-mail et le chat en direct, là où vous les avez configurés.
| Champ | Contenu |
|---|---|
message | Obligatoire. Le texte, jusqu'à 10 000 caractères. |
conversationId | Facultatif. Poursuit une conversation que vous avez démarrée via l'API, avec le conversationId d'une réponse précédente. |
sessionId | Facultatif. Votre propre identifiant pour la personne au nom de laquelle vous discutez, par exemple votre identifiant utilisateur, jusqu'à 100 caractères. La même valeur poursuit toujours la même conversation. Vous pouvez aussi envoyer le sessionId d'une réponse précédente. |
stream | Facultatif. true envoie le texte de la réponse en streaming ; voir Streaming. La valeur par défaut est false. |
timeZone | Facultatif. Le fuseau horaire IANA de la personne, par exemple Europe/Berlin, pour les horaires de réservation. Sans lui, les horaires sont en UTC. |
Sans conversationId ni sessionId, chaque message démarre une nouvelle conversation.
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/chat \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "Do you ship to Switzerland?", "sessionId": "customer-4821" }'
{
"reply": "Yes, we ship to Switzerland. Delivery takes 3 to 5 working days.",
"conversationId": "CONVERSATION_ID",
"sessionId": "icapi5f0c2b9e4d7a41f8a3c6e1b2d9f07a64",
"sources": [
{ "title": "Shipping", "url": "https://www.example.com/shipping" }
],
"followUps": ["How much does shipping cost?", "Can I track my order?"],
"buttons": [],
"products": [],
"form": null,
"leadForm": null,
"booking": null,
"liveChat": null
}
| Champ | Contenu |
|---|---|
reply | La réponse de l'agent en texte brut avec Markdown, sans les blocs de contrôle du widget. Vide tant qu'une personne de votre équipe a la main sur le chat (voir liveChat). |
conversationId | La conversation, comme dans Obtenir une conversation. |
sessionId | La session de la conversation dans intoCHAT. Elle commence toujours par icapi. |
sources | Les pages sur lesquelles s'appuie la réponse, avec title et url, quand Show sources under replies est activé. Les pages issues de la recherche web sont toujours listées, avec "web": true. |
followUps | Les questions suivantes suggérées, quand Suggest follow-up questions est activé. |
buttons | Les boutons personnalisés choisis par l'agent, avec label et url. |
products | Les fiches produits de votre boutique ou de vos actions API, avec name, url et, quand ils sont connus, image, price, compareAtPrice, currency et available. |
form | Un formulaire de chat proposé par l'agent, avec son formId, son name, ses fields et son submitLabel, ou null. L'API ne peut pas l'envoyer ; affichez-le dans votre propre interface ou ignorez-le. |
leadForm | Le formulaire de leads, avec son message, ses fields de contact et form, quand l'agent a demandé des coordonnées, ou null. Les coordonnées écrites dans un message sont enregistrées comme lead quand Save contact details written in the chat est activé, comme dans le widget. |
booking | Les créneaux de rendez-vous disponibles, avec provider, eventTitle, eventLength en minutes, timeZone et days, chacun avec sa date et ses slots en heures UTC, ou null. L'API ne peut pas réserver de créneau. |
liveChat | null, ou l'état du chat en direct : offered (l'agent peut demander à votre équipe de rejoindre le chat), requested (il le lui a demandé) ou paused (un membre de l'équipe a la main sur le chat, l'agent n'a donc pas répondu). |
Différences entre les chats API et le widget
- La conversation est enregistrée comme un chat du widget et apparaît dans l'onglet Conversations de l'agent, avec ses leads, ses notes et ses statistiques. Elle n'a ni pays ni page.
- Les domaines autorisés, les pays bloqués et les messages par visiteur ne s'appliquent pas : il n'y a ni page ni adresse de visiteur à vérifier. Les messages de l'offre, le plafond mensuel de l'agent et la limite de débit de la clé s'appliquent.
- Un agent privé refuse les chats API avec
agent_private. - Les actions côté client s'exécutent dans le navigateur d'un visiteur : elles ne sont donc pas proposées à l'agent dans les chats API. Les actions API, les boutons, les formulaires et la réservation fonctionnent.
- Impossible de joindre des fichiers, et il n'y a pas de chats temporaires.
- Seules les conversations démarrées via l'API peuvent être poursuivies via l'API. L'agent voit les 40 derniers messages de la conversation comme historique.
- Tant qu'une personne de votre équipe a pris la main sur le chat dans la boîte de réception Live chat, votre message est enregistré,
replyest vide etliveChatvautpaused. Les réponses du membre de l'équipe apparaissent dans la conversation : lisez-les avec Obtenir une conversation, où elles ont unauthorName. Un message pendant une prise en main ne consomme aucun message de votre offre. - Une réponse qui prend plus de 55 secondes se termine par une erreur
504avec le codetimeout. Elle peut tout de même compter comme un message.
Streaming
Avec "stream": true, la réponse est le texte de la réponse au fur et à mesure de sa rédaction, en text/plain, sans les champs JSON. Les en-têtes X-Conversation-Id et X-Session-Id indiquent la conversation et la session, et X-Live-Chat l'état du chat en direct s'il y en a un. Les sources, les boutons et les autres blocs ne sont pas envoyés en streaming ; lisez-les ensuite avec Obtenir une conversation. Les erreurs sont en JSON, comme sans streaming.
curl -N https://www.intochat.ai/api/v1/agents/AGENT_ID/chat \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "What are your opening hours?", "stream": true }'
Lister les conversations
GET /api/v1/agents/{agentId}/conversations · scope conversations:read
Les conversations de l'agent, depuis le widget et l'API, les plus récentes en premier, sans leurs messages. Accepte limit, cursor et since ; voir Pagination.
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/conversations?limit=50&since=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "CONVERSATION_ID",
"sessionId": "8f14e45f-ceea-467a-9575-1a2b3c4d5e6f",
"channel": "widget",
"createdAt": "2026-10-04T09:00:00.000Z",
"lastActivityAt": "2026-10-04T09:12:00.000Z",
"country": "CH",
"page": "https://www.example.com/pricing",
"messageCount": 6,
"topics": ["Pricing"],
"sentiment": "positive",
"liveChat": null,
"csatScore": null
}
],
"hasMore": false,
"nextCursor": null
}
channel vaut api pour une conversation démarrée via l'API, sinon widget (la balise script, l'iframe dans la page, le lien direct et le Playground). topics et sentiment sont définis par l'analyse des thèmes quand elle est activée. liveChat vaut null, requested, active ou ended. csatScore est la note de 1 à 5 donnée par le visiteur après un chat en direct, ou null.
Obtenir une conversation
GET /api/v1/conversations/{conversationId} · scope conversations:read
Une conversation de n'importe quel agent du compte, avec tous ses messages dans l'ordre.
{
"data": {
"id": "CONVERSATION_ID",
"agentId": "AGENT_ID",
"sessionId": "icapi5f0c2b9e4d7a41f8a3c6e1b2d9f07a64",
"channel": "api",
"createdAt": "2026-10-04T09:00:00.000Z",
"lastActivityAt": "2026-10-04T09:14:00.000Z",
"country": null,
"page": null,
"topics": [],
"sentiment": null,
"handoffRequestedAt": null,
"liveChat": { "status": "ended", "startedAt": "2026-10-04T09:05:00.000Z", "endedAt": "2026-10-04T09:13:00.000Z" },
"csat": { "score": 5, "comment": "Quick and friendly.", "ratedAt": "2026-10-04T09:14:00.000Z" },
"messages": [
{ "id": "MESSAGE_ID", "role": "assistant", "content": "Hello! How can I help you today?", "createdAt": "2026-10-04T09:00:00.000Z", "authorName": null, "sources": [] },
{ "id": "MESSAGE_ID", "role": "user", "content": "Can I change my delivery address?", "createdAt": "2026-10-04T09:01:00.000Z", "authorName": null, "sources": [] },
{ "id": "MESSAGE_ID", "role": "assistant", "content": "Yes, I'm on it. What's your order number?", "createdAt": "2026-10-04T09:06:00.000Z", "authorName": "Anna", "sources": [] }
]
}
}
role vaut user pour le visiteur ou vos messages API, et assistant pour l'agent et votre équipe. authorName est le prénom du membre de l'équipe qui a rédigé une réponse en chat en direct, ou null quand c'est l'agent qui l'a rédigée. content est le texte sans les blocs de contrôle du widget ; les sources d'une réponse de l'agent listent les pages qu'elle a affichées. handoffRequestedAt est le moment où l'agent a envoyé la conversation à votre équipe par e-mail, ou null. liveChat et csat valent null quand il n'y a eu ni chat en direct ni note.
Lister les leads
GET /api/v1/agents/{agentId}/leads · scope leads:read
Les leads de l'agent, les plus récents en premier. Accepte limit, cursor et since ; voir Pagination.
{
"data": [
{
"id": "LEAD_ID",
"email": "jane@example.com",
"phone": null,
"name": "Jane",
"customFields": [{ "id": "FIELD_ID", "label": "Company", "value": "Acme" }],
"source": "form",
"conversationId": "CONVERSATION_ID",
"collectedAt": "2026-10-04T09:03:00.000Z",
"lastSeenAt": "2026-10-04T09:03:00.000Z",
"submissionCount": 1
}
],
"hasMore": false,
"nextCursor": null
}
source vaut form pour le formulaire de leads ou chat pour des coordonnées écrites dans un message. customFields utilise les libellés actuels de votre formulaire. lastSeenAt et submissionCount changent quand la même personne envoie de nouveau ses coordonnées. conversationId vaut null quand la conversation a été supprimée.
Contacts
Les contacts d'un agent : visiteurs vérifiés, leads, contacts importés et ceux que vous ajoutez ici, chacun avec jusqu'à 50 attributs personnalisés. Les lire nécessite leads:read ; les créer, les modifier et les supprimer nécessite contacts:write. Les clés créées avec Every scope ont les deux.
Un contact se présente ainsi :
{
"id": "CONTACT_ID",
"agentId": "AGENT_ID",
"externalId": "user-4711",
"email": "jane@example.com",
"phone": "+41441234567",
"name": "Jane",
"attributes": { "plan": "pro", "seats": 5, "vip": true },
"source": "api",
"firstSeenAt": "2026-10-04T09:03:00.000Z",
"lastSeenAt": "2026-10-04T09:03:00.000Z",
"createdAt": "2026-10-04T09:03:00.000Z",
"updatedAt": "2026-10-04T09:03:00.000Z"
}
source vaut identity, lead, import ou api : la provenance d'origine du contact. externalId est l'identifiant d'utilisateur de la personne sur votre site. Les e-mails sont enregistrés en minuscules.
Lister les contacts
GET /api/v1/agents/{agentId}/contacts · scope leads:read
Les contacts de l'agent, les plus récents en premier. Accepte limit, cursor et since (les contacts modifiés à partir de ce moment) ; voir Pagination. Ajoutez email= ou external_id= pour rechercher un contact.
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/contacts?external_id=user-4711" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{ "data": [ { "id": "CONTACT_ID", "externalId": "user-4711", "email": "jane@example.com", "attributes": { "plan": "pro" } } ], "hasMore": false, "nextCursor": null }
data contient tous les champs présentés plus haut ; certains sont omis ici.
Créer ou mettre à jour un contact
POST /api/v1/agents/{agentId}/contacts · scope contacts:write
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/contacts \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "external_id": "user-4711", "email": "jane@example.com", "name": "Jane", "attributes": { "plan": "pro", "seats": 5 } }'
| Champ | Contenu |
|---|---|
external_id | Jusqu'à 200 caractères. Envoyez ce champ ou email. |
email | Une adresse e-mail valide. |
phone | De 7 à 15 chiffres, éventuellement précédés de +. |
name | Jusqu'à 100 caractères. |
attributes | Un objet de noms et de valeurs d'attributs. Les noms commencent par une lettre minuscule et utilisent des lettres minuscules, des chiffres et des tirets bas, jusqu'à 40 caractères ; voir Attributs. Une valeur est un texte de 1 000 caractères au plus, un nombre ou true/false, et null retire l'attribut. |
Le contact qui a cet external_id est mis à jour, sinon celui qui a cet email, sinon un nouveau contact est créé. Un contact sans identifiant externe retrouvé ainsi par son e-mail reçoit l'external_id. Les champs que vous envoyez remplacent ce qui est enregistré, un champ défini à null est vidé, et les champs que vous omettez restent inchangés. Les attributs sont fusionnés : ceux que vous envoyez sont définis, les autres sont conservés.
{ "data": { "id": "CONTACT_ID", "externalId": "user-4711", "email": "jane@example.com", "attributes": { "plan": "pro", "seats": 5 } }, "result": "created" }
result vaut created (statut 201) ou updated (statut 200). Un e-mail qui appartient à un contact ayant un autre identifiant externe, ou un identifiant externe ou un e-mail qu'un autre contact a déjà, reçoit une erreur 409 avec le code conflict. Un nouveau contact au-delà des contacts par agent de votre offre reçoit une erreur 403 avec le code contact_limit_reached.
Obtenir un contact
GET /api/v1/contacts/{contactId} · scope leads:read
Un contact de n'importe quel agent du compte, sous la forme { "data": { … } }.
Modifier un contact
PATCH /api/v1/contacts/{contactId} · scope contacts:write
Accepte les mêmes champs que Créer ou mettre à jour un contact, tous facultatifs, et répond avec le contact sous la forme { "data": { … } }. Un contact doit garder un identifiant externe, un e-mail ou un numéro de téléphone.
Supprimer un contact
DELETE /api/v1/contacts/{contactId} · scope contacts:write
{ "data": { "id": "CONTACT_ID", "deleted": true } }
Les leads et les conversations du contact sont conservés.
Lister les sources
GET /api/v1/agents/{agentId}/sources · scope sources:read
Les sources de connaissances de l'agent, dans l'ordre de son onglet Knowledge, avec la progression de l'entraînement. Le texte d'une source n'est pas inclus, sauf la question et la réponse d'une paire de questions-réponses.
{
"data": [
{
"id": "SOURCE_ID",
"type": "qa",
"title": "Do you ship to Switzerland?",
"url": null,
"filename": null,
"question": "Do you ship to Switzerland?",
"answer": "Yes, in 3 to 5 working days.",
"characters": 71,
"status": "trained",
"error": null,
"trainedAt": "2026-10-02T09:00:00.000Z",
"createdAt": "2026-10-02T08:59:00.000Z",
"updatedAt": "2026-10-02T09:00:00.000Z"
}
],
"training": { "total": 18, "trained": 18, "pending": 0, "processing": 0, "failed": 0, "done": true },
"characters": { "used": 48210, "limit": 500000 }
}
type vaut website, file, text, qa ou notion. status vaut pending, processing, trained ou failed, avec la raison dans error. characters.limit correspond aux caractères d'entraînement par agent de votre offre.
Ajouter une source
POST /api/v1/agents/{agentId}/sources · scope sources:write
Ajoute un extrait de texte ou une paire de questions-réponses et lance l'entraînement, comme le fait l'onglet Knowledge. L'agent utilise la nouvelle source une fois qu'elle est entraînée ; suivez son status avec Lister les sources.
Un extrait de texte :
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/sources \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "text", "title": "Opening hours", "content": "We are open Monday to Friday, 9:00 to 17:00." }'
Une paire de questions-réponses :
{ "type": "qa", "question": "Do you ship to Switzerland?", "answer": "Yes, in 3 to 5 working days." }
{
"data": { "id": "SOURCE_ID", "type": "text", "title": "Opening hours", "status": "pending", "characters": 44 },
"result": "created",
"training": { "total": 19, "trained": 18, "pending": 1, "processing": 0, "failed": 0, "done": false }
}
data contient tous les champs de Lister les sources ; certains sont omis ci-dessus. result vaut created (statut 201), updated quand une paire de questions-réponses avec la même question, sans tenir compte des majuscules et minuscules, existait déjà et a maintenant la nouvelle réponse, ou unchanged quand elle avait exactement cette réponse (tous deux avec le statut 200). Un extrait de texte est toujours ajouté comme nouvelle source. Un titre et une question peuvent chacun compter jusqu'à 200 caractères.
La source compte dans les caractères d'entraînement de l'agent. Une source qui dépasserait la limite de votre offre reçoit une erreur 403 avec le code character_limit_exceeded, et rien n'est ajouté. Voir Caractères d'entraînement par agent.
Supprimer une source
DELETE /api/v1/agents/{agentId}/sources/{sourceId} · scope sources:write
Supprime immédiatement la source et ce que l'agent en a appris, comme le fait la suppression dans l'onglet Knowledge. Rien d'autre n'a besoin d'être réentraîné.
{ "id": "SOURCE_ID", "deleted": true, "training": { "total": 17, "trained": 17, "pending": 0, "processing": 0, "failed": 0, "done": true } }
Abonner un webhook
POST /api/v1/agents/{agentId}/webhooks · scope webhooks:write
Abonne un webhook aux événements de l'agent : un REST hook, tel que l'utilisent les déclencheurs instantanés de Zapier et de Make. intoCHAT envoie ensuite chaque événement à l'adresse comme décrit dans Webhooks, signé et retenté comme un webhook ajouté dans l'onglet Leads.
| Champ | Contenu |
|---|---|
url | Obligatoire. L'adresse à laquelle envoyer les événements. Comme dans l'onglet Leads, elle doit commencer par https:// et pointer vers un serveur public ; les adresses de réseaux privés ou internes sont refusées. |
events | Obligatoire. Un ou plusieurs événements parmi lead.created, handoff.requested, form.submitted, booking.created, live_chat.requested et return.requested. Voir Événements. |
source | Facultatif. zapier, make ou api (la valeur par défaut) : ce que l'onglet Leads affiche à côté du webhook, par exemple via Zapier. |
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/webhooks \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://hooks.example.com/intochat", "events": ["lead.created"], "source": "api" }'
{
"id": "WEBHOOK_ID",
"agentId": "AGENT_ID",
"url": "https://hooks.example.com/intochat",
"events": ["lead.created"],
"source": "api",
"secret": "whsec_…",
"createdAt": "2026-10-08T09:00:00.000Z"
}
La réponse a le statut 201. Conservez id pour vous désabonner plus tard. secret est le secret de signature du webhook, renvoyé uniquement ici ; utilisez-le pour vérifier la signature si votre récepteur le peut. Les outils qui ne savent pas vérifier les signatures, comme Zapier et Make, peuvent l'ignorer.
Un webhook abonné apparaît dans l'onglet Leads de l'agent avec un badge via Zapier, via Make ou via API, où le propriétaire peut le mettre en pause ou le retirer. Il garde en mémoire la clé qui l'a abonné : révoquer cette clé le supprime. Un agent peut avoir jusqu'à 25 webhooks abonnés, en plus des 5 ajoutés dans l'onglet Leads ; au-delà, la requête reçoit une erreur 400.
Désabonner un webhook
DELETE /api/v1/webhooks/{webhookId} · scope webhooks:write
Supprime un webhook abonné via l'API, avec son historique d'envois. N'importe quelle clé du même compte peut le faire. Un webhook ajouté dans l'onglet Leads, le webhook d'un autre compte ou un webhook déjà retiré reçoit 404.
{ "id": "WEBHOOK_ID", "deleted": true }
Lister les événements
GET /api/v1/agents/{agentId}/events/{event} · scope agents:read, plus leads:read ou conversations:read
Les derniers événements d'un type pour l'agent, les plus récents en premier, chacun exactement de la même forme que le corps d'un envoi de webhook. Les outils d'automatisation l'interrogent au lieu d'attendre un webhook, par exemple pour afficher de vrais exemples de données. Accepte limit, de 1 à 100 (20 par défaut).
event | Nécessite aussi | Construit à partir de |
|---|---|---|
lead.created | leads:read | Les leads, les derniers enregistrés en premier |
form.submitted | leads:read | Les formulaires reçus |
booking.created | leads:read | Les réservations |
return.requested | leads:read | Les demandes de retour |
handoff.requested | conversations:read | Les conversations transférées par e-mail |
live_chat.requested | conversations:read | Les conversations dans lesquelles l'agent a demandé à votre équipe de rejoindre le chat |
conversation.created | conversations:read | Les nouvelles conversations. Cet événement n'a pas de webhook ; il peut seulement être listé. |
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/events/lead.created?limit=5" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "LEAD_ID",
"event": "lead.created",
"created_at": "2026-10-07T09:30:00.000Z",
"agent": { "id": "AGENT_ID", "name": "Acme Assistant" },
"data": {
"leadId": "LEAD_ID",
"agentId": "AGENT_ID",
"agentName": "Acme Assistant",
"email": "jane@example.com",
"phone": null,
"name": "Jane",
"customFields": [],
"source": "form",
"conversationId": "CONVERSATION_ID",
"collectedAt": "2026-10-07T09:30:00.000Z"
}
}
]
}
Les différences avec un envoi :
idest l'identifiant de l'enregistrement, pas un identifiant d'envoi : un même événement a donc toujours le mêmeid, à savoir l'identifiant du lead, de l'envoi de formulaire, de la réservation, de la demande de retour ou de la conversation. Pour les transferts et les demandes de chat en direct, il s'agit de l'identifiant de la conversation, suivi de deux-points et de l'heure en millisecondes, car une conversation peut redemander plus tard.created_atest le moment où l'enregistrement a été sauvegardé.- Les données sont reconstituées à partir de ce qu'intoCHAT conserve. Le
summaryd'un transfert n'est pas conservé : il vaut doncnull, ettestvautfalse. Un transfert qui a ouvert un ticket helpdesk contient sonticket, comme le webhook. LeproviderStatusd'une réservation vautpendingtant qu'elle attend votre confirmation, sinonaccepted. Une demande de retour a sonstatusactuel,requestedouhandled. - Les données de
conversation.createdcontiennentconversationId,channel(widgetouapi),page,countryetcreatedAt.
Obtenir des exemples d'événements
GET /api/v1/agents/{agentId}/events/{event}/samples · scope agents:read
Jusqu'à 3 des derniers événements de l'agent, comme dans Lister les événements, pour qu'un outil ait toujours des données à partir desquelles associer les champs. Quand l'agent n'en a pas encore, ou que la clé n'a pas le scope dont cet événement a besoin (leads:read ou conversations:read), il renvoie à la place un exemple documenté avec les mêmes champs, et sample vaut true.
{
"data": [
{
"id": "sample_booking.created",
"event": "booking.created",
"created_at": "2026-10-07T09:30:00.000Z",
"agent": { "id": "AGENT_ID", "name": "Acme Assistant" },
"data": { "bookingId": "sample_booking", "eventTitle": "30 min intro call", "attendeeEmail": "jane@example.com" }
}
],
"sample": true
}
Le data de l'exemple contient tous les champs de l'événement ; certains sont omis ci-dessus.
Limites
- L'API est incluse à partir de Starter. Avec l'offre Free, aucune clé ne peut être créée et les clés existantes reçoivent
plan_required. - 60 requêtes par minute et par clé, et 20 clés actives au maximum par compte.
- Chaque réponse de chat compte comme un message de votre offre. Un agent répond à 1 000 messages par heure au maximum, widget et API confondus.
- Une réponse de chat doit se terminer en 55 secondes.
- Sources : extraits de texte et paires de questions-réponses uniquement. Les pages de site, les fichiers et les pages Notion s'ajoutent dans le tableau de bord.
- Jusqu'à 25 webhooks abonnés par agent, en plus des 5 ajoutés dans l'onglet Leads.
- Les contacts sont créés et mis à jour un par un. Pour en ajouter beaucoup à la fois, utilisez Importer un fichier CSV dans le tableau de bord.
- Il n'existe pas encore de points de terminaison pour créer ou modifier des agents, envoyer des formulaires, réserver des rendez-vous ou prendre la main sur des chats en direct.
Étapes suivantes
- Recevez les leads et les transferts sur votre serveur au moment où ils se produisent : Webhooks.
- Utilisez intoCHAT dans Zapier ou Make : Zapier et Make.
- Laissez votre agent appeler votre propre API pendant qu'il répond : Actions API.
- Rédigez de bons extraits de texte et de bonnes paires de questions-réponses : Texte et questions-réponses.
- Vérifiez ce que comprend votre offre : Offres et limites.