Vue d'ensemble de l'API
Chaque endpoint REST de RolChat suit un même contrat : la même URL de base, la même enveloppe de réponse, la même pagination, la même forme d’erreur. Apprenez-le une fois et chaque famille d’endpoints de la référence des endpoints se lit de la même façon.
URL de base et versions
Section intitulée « URL de base et versions »https://api.rolchat.com/api/v1/La version figure dans le chemin. Ajouter des champs facultatifs, de nouveaux endpoints ou de nouveaux paramètres de requête avec des valeurs par défaut ne constitue pas un changement incompatible et ne change pas la version. Les changements incompatibles sont publiés en v2, et les endpoints v1 dépréciés continuent de fonctionner pendant au moins six mois après leur annonce (voir Dépréciation).
Authentification
Section intitulée « Authentification »| Méthode | En-tête | Usage |
|---|---|---|
| JWT bearer | Authorization: Bearer <access_token> |
Sessions interactives (l’application web, les applications mobiles) |
| Clé d’API | Authorization: Bearer rcp_<secret> |
Appels de machine à machine, clés d’API de plugins |
| Signature HMAC | X-RolChat-Signature: sha256=… |
Webhooks entrants depuis vos systèmes, voir Webhooks |
| Aucune | - | Endpoints publics du widget (/widget/…, /forms/…), limités par site et par origine |
Pour les intégrations, utilisez une clé d’API (un jeton d’accès personnel). Les clés se créent dans Paramètres → Plugins → Clés d’API RolChat, ne sont affichées qu’une fois et ne sont stockées que sous forme de hachage. Une clé ne peut jamais faire plus que le membre qui l’a créée : ses portées sont comparées aux permissions actuelles de ce membre à chaque appel. Voir Authentification pour la durée de vie des JWT, l’en-tête X-Account-Id et les sessions multi-entreprises.
Enveloppe de réponse
Section intitulée « Enveloppe de réponse »Une ressource unique :
{ "data": { "id": "cnt_01HK…", "email": "ada@example.com" }, "meta": { "request_id": "req_01HK…" }}Une liste :
{ "data": [ { … }, { … } ], "meta": { "request_id": "req_01HK…", "count": 50, "next_cursor": "cur_01HK…", "prev_cursor": "cur_01HK…", "has_more": true }}Les réponses sans corps (204 No Content après une suppression) portent tout de même l’en-tête X-Request-Id.
Une erreur :
{ "errors": [ { "code": "validation_failed", "message": "Email must be valid.", "field": "email", "details": { "received": "not-an-email" } } ], "meta": { "request_id": "req_01HK…" }}code est une valeur lisible par machine en snake_case, sur laquelle baser votre logique ; message est en anglais et destiné aux journaux. field et details sont présents lorsqu’ils sont utiles et ne contiennent jamais de données personnelles. L’API ne répond jamais 200 avec un tableau errors : en présence d’erreurs, le statut est 400 ou plus. La liste complète des codes se trouve sur la page Erreurs.
Pagination
Section intitulée « Pagination »Les endpoints de liste susceptibles de grossir utilisent la pagination par curseur. Demandez la première page sans curseur, puis renvoyez tel quel le next_cursor reçu :
GET /api/v1/contacts?limit=50GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…limitvaut 50 par défaut et est plafonné à 200 ; les valeurs supérieures sont rejetées avec400 validation_failed.- Les curseurs sont opaques et expirent après 24 heures (
400 validation_failedaveccode: cursor_expired). - Les résultats sont cohérents avec l’instantané pris à la première page : les fiches supprimées entre deux pages disparaissent, les nouvelles fiches n’apparaissent que lorsque vous recommencez sans curseur.
- Un en-tête
Linkavecrel="next"etrel="prev"est également envoyé pour les clients qui le préfèrent.
Idempotence
Section intitulée « Idempotence »Envoyez un en-tête Idempotency-Key (un UUID ou un ULID, jusqu’à 255 caractères) avec tout POST, PATCH ou DELETE :
- La première requête portant une clé s’exécute, et son statut et son corps sont conservés pendant 24 heures.
- Une répétition avec la même clé et le même corps renvoie la réponse conservée sans réexécuter les effets de bord.
- Une répétition avec la même clé mais un corps différent est rejetée avec
409 idempotency_key_conflict.
Utilisez-la pour chaque appel qui crée quelque chose avec des effets de bord : envoi d’un message, d’un e-mail ou d’un SMS, passage d’un appel, tout ce qui est facturé. Les requêtes GET sont toujours idempotentes et ignorent l’en-tête.
Limites de débit
Section intitulée « Limites de débit »Les limites sont comptées par minute et calculées par compte, par clé d’API ou par utilisateur (par adresse IP sur les routes qui ne demandent pas de connexion). Les plafonds par défaut :
| Seau | Limite par défaut | Par minute |
|---|---|---|
| Requêtes sans connexion (par IP) | 60 | par IP |
| Utilisateur connecté (tableau de bord) | 1 000 | par utilisateur |
| Clé d’API | 1 000 | par clé |
| Endpoints publics du widget | 60 par visiteur, et 600 par adresse réseau | par minute |
Connexion (/auth/login) |
5 | par IP |
| Webhooks entrants | 300 | par minute |
| Serveur MCP | 600 | par minute |
| Endpoints OAuth | 600 | par minute |
Ces plafonds sont les valeurs par défaut de la plateforme et l’opérateur peut les modifier ; votre forfait ne les multiplie pas, et les limites Enterprise sont fixées dans votre contrat. Les endpoints soumis à une limite renvoient :
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 543Lorsque vous dépassez une limite, la réponse est 429 avec code: rate_limited dans le tableau errors et un en-tête Retry-After en secondes. Attendez ce délai avant l’appel suivant. Dix échecs de connexion verrouillent le compte pendant 30 minutes.
Tailles et délais d’expiration
Section intitulée « Tailles et délais d’expiration »| Catégorie | Corps de requête maximal | Délai d’expiration côté serveur |
|---|---|---|
| Par défaut | 1 MB | 30 s |
| Message avec pièces jointes | 25 MB | 30 s |
| Import CSV | 50 MB | renvoie 202 et s’exécute en arrière-plan |
| Images de la base de connaissances | 10 MB | 30 s |
| API en masse | 10 MB | 30 s |
| Recherche | 1 MB | 10 s |
| Requêtes IA | 1 MB | 60 s |
| Endpoints du widget | 100 KB | 30 s |
Les corps trop volumineux reçoivent 413 payload_too_large. Un service en amont qui dépasse le délai répond 504 avec code: upstream_timeout et une indication retry_after lorsqu’une nouvelle tentative peut aider.
Types de contenu, dates et identifiants
Section intitulée « Types de contenu, dates et identifiants »- Les requêtes et les réponses sont en
application/json; charset=utf-8. Les envois de fichiers utilisentmultipart/form-data; les exports CSV renvoienttext/csv. L’UTF-8 invalide est rejeté avec400 validation_failed. - Les horodatages sont au format ISO-8601 en UTC avec une précision à la milliseconde :
2026-04-20T14:23:45.123Z. Tout décalage ISO-8601 est accepté en entrée et normalisé en UTC. - Les identifiants sont des ULID ou des UUID opaques. Il n’y a pas d’identifiants numériques, et les adresses e-mail ou numéros de téléphone n’apparaissent jamais dans une URL.
Isolation des locataires et permissions
Section intitulée « Isolation des locataires et permissions »Chaque requête authentifiée s’exécute dans un seul compte. Une ressource qui appartient à un autre compte, ou à un site que le rôle de l’appelant ne couvre pas, renvoie 404 not_found plutôt que 403, afin de ne jamais révéler l’existence de fiches. Un jeton valide sans la permission requise (par exemple contacts.delete) renvoie 403 forbidden. Certaines permissions portent un suffixe de périmètre (conversations.read:own, :team, :all) qui restreint ce que renvoie une liste.
PATCH n’accepte que les champs modifiables. id, account_id, created_at, updated_at et les champs d’état comme resolved_at sont en lecture seule ; en envoyer un renvoie 400 validation_failed avec details.forbidden_fields. Les changements d’état passent par des actions dédiées comme POST /tickets/:id/resolve.
Chaque écriture est enregistrée dans le journal d’audit du compte.
En-têtes d’observabilité
Section intitulée « En-têtes d’observabilité »Chaque réponse contient :
X-Request-Id: req_01HK…Journalisez X-Request-Id. C’est la première chose que demande le support.
L’origine du tableau de bord dans le navigateur est https://app.rolchat.com. Les endpoints publics du widget acceptent toutes les origines, ou uniquement celles que vous vérifiez pour un site. Les appels de serveur à serveur avec une clé d’API ne sont pas soumis à CORS.
Dépréciation
Section intitulée « Dépréciation »- Le changement est annoncé dans le journal des modifications et l’endpoint concerné commence à envoyer
Deprecation: trueet un en-têteSunsetavec la date de retrait. - Les endpoints publics continuent de fonctionner pendant au moins six mois après l’annonce.
- Le retrait n’a lieu que dans une nouvelle version majeure. Au sein de
v1, les changements sont uniquement additifs.
Chaque service expose /healthz (vivacité) et /readyz (disponibilité).