API-overzicht
Elk REST-endpoint van RolChat volgt één contract: dezelfde basis-URL, dezelfde response-envelop, dezelfde paginering, dezelfde vorm voor fouten. Leer het één keer en elke endpointfamilie in de endpointreferentie leest op dezelfde manier.
Basis-URL en versiebeheer
Section titled “Basis-URL en versiebeheer”https://api.rolchat.com/api/v1/De versie staat in het pad. Optionele velden, nieuwe endpoints of nieuwe queryparameters met standaardwaarden toevoegen is geen brekende wijziging en verhoogt de versie niet. Brekende wijzigingen verschijnen als v2, en uitgefaseerde v1-endpoints blijven na de aankondiging nog minstens zes maanden werken (zie Uitfasering).
Authenticatie
Section titled “Authenticatie”| Methode | Header | Gebruikt voor |
|---|---|---|
| JWT bearer | Authorization: Bearer <access_token> |
Interactieve sessies (de webapp, mobiele apps) |
| API-sleutel | Authorization: Bearer rcp_<secret> |
Aanroepen tussen machines, API-sleutels van plug-ins |
| HMAC-handtekening | X-RolChat-Signature: sha256=… |
Inkomende webhooks vanuit je eigen systemen, zie Webhooks |
| Geen | - | Openbare widgetendpoints (/widget/…, /forms/…), afgebakend op site en origin |
Gebruik voor integraties een API-sleutel (een persoonlijk toegangstoken). Sleutels maak je aan in Instellingen → Plug-ins → RolChat-API-sleutels; ze worden één keer getoond en alleen als hash opgeslagen. Een sleutel kan nooit meer dan het lid dat hem heeft aangemaakt: bij elke aanroep worden de scopes gecontroleerd tegen de huidige rechten van dat lid. Zie Authenticatie voor de levensduur van JWT’s, de header X-Account-Id en sessies met meerdere bedrijven.
Response-envelop
Section titled “Response-envelop”Eén resource:
{ "data": { "id": "cnt_01HK…", "email": "ada@example.com" }, "meta": { "request_id": "req_01HK…" }}Een lijst:
{ "data": [ { … }, { … } ], "meta": { "request_id": "req_01HK…", "count": 50, "next_cursor": "cur_01HK…", "prev_cursor": "cur_01HK…", "has_more": true }}Responses zonder body (204 No Content na een verwijdering) bevatten toch de header X-Request-Id.
Een fout:
{ "errors": [ { "code": "validation_failed", "message": "Email must be valid.", "field": "email", "details": { "received": "not-an-email" } } ], "meta": { "request_id": "req_01HK…" }}code is machineleesbare snake_case en is de waarde waarop je vertakt; message is Engelstalig en bedoeld voor logboeken. field en details zijn aanwezig als ze helpen en bevatten nooit persoonsgegevens. De API antwoordt nooit met 200 en een errors-array: zijn er fouten, dan is de status 400 of hoger. De volledige lijst met codes staat op de pagina Fouten.
Paginering
Section titled “Paginering”Lijstendpoints die kunnen groeien, gebruiken cursorpaginering. Vraag de eerste pagina op zonder cursor en geef daarna de ontvangen next_cursor letterlijk terug:
GET /api/v1/contacts?limit=50GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…limitis standaard 50 en maximaal 200; grotere waarden worden geweigerd met400 validation_failed.- Cursors zijn ondoorzichtig en verlopen na 24 uur (
400 validation_failedmetcode: cursor_expired). - Resultaten zijn consistent met de momentopname van de eerste pagina: records die tussen pagina’s worden verwijderd, verdwijnen; nieuwe records verschijnen pas als je opnieuw begint zonder cursor.
- Voor clients die dat prefereren, wordt ook een
Link-header metrel="next"enrel="prev"meegestuurd.
Idempotentie
Section titled “Idempotentie”Stuur bij elke POST, PATCH of DELETE een header Idempotency-Key mee (een UUID of ULID, tot 255 tekens):
- Het eerste verzoek met een sleutel wordt uitgevoerd en de status en body worden 24 uur bewaard.
- Een herhaling met dezelfde sleutel en dezelfde body geeft de bewaarde response terug zonder de neveneffecten opnieuw uit te voeren.
- Een herhaling met dezelfde sleutel maar een andere body wordt geweigerd met
409 idempotency_key_conflict.
Gebruik dit bij elke aanroep die iets met neveneffecten aanmaakt: een bericht, e-mail of sms versturen, een gesprek starten, alles wat kosten oplevert. GET-verzoeken zijn altijd idempotent en negeren de header.
Snelheidslimieten
Section titled “Snelheidslimieten”Limieten worden per minuut geteld en gelden per account, API-sleutel of gebruiker (per IP-adres op routes waarvoor geen inlog nodig is). De standaardplafonds:
| Groep | Standaardlimiet | Per minuut |
|---|---|---|
| Verzoeken zonder inlog (per IP-adres) | 60 | per IP-adres |
| Ingelogde gebruiker (dashboard) | 1.000 | per gebruiker |
| API-sleutel | 1.000 | per sleutel |
| Openbare widgetendpoints | 60 per bezoeker en 600 per netwerkadres | per minuut |
Inloggen (/auth/login) |
5 | per IP-adres |
| Inkomende webhooks | 300 | per minuut |
| MCP-server | 600 | per minuut |
| OAuth-endpoints | 600 | per minuut |
De plafonds zijn de standaardwaarden van het platform en kunnen door de operator worden gewijzigd; je abonnement vermenigvuldigt ze niet, en Enterprise-limieten worden in je contract afgesproken. Endpoints met een snelheidslimiet geven terug:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 543Overschrijd je een limiet, dan is de response 429 met code: rate_limited in de errors-array en een header Retry-After in seconden. Wacht zo lang voor de volgende aanroep. Tien mislukte inlogpogingen blokkeren het account voor 30 minuten.
Groottes en time-outs
Section titled “Groottes en time-outs”| Categorie | Maximale requestbody | Time-out van de server |
|---|---|---|
| Standaard | 1 MB | 30 s |
| Bericht met bijlagen | 25 MB | 30 s |
| CSV-import | 50 MB | geeft 202 terug en draait op de achtergrond |
| Afbeeldingen voor de kennisbank | 10 MB | 30 s |
| Bulk-API | 10 MB | 30 s |
| Zoeken | 1 MB | 10 s |
| AI-verzoeken | 1 MB | 60 s |
| Widgetendpoints | 100 KB | 30 s |
Te grote bodies krijgen 413 payload_too_large. Een upstream met een time-out antwoordt 504 met code: upstream_timeout en een hint retry_after wanneer een nieuwe poging kan helpen.
Contenttypen, datums en ID’s
Section titled “Contenttypen, datums en ID’s”- Verzoeken en responses zijn
application/json; charset=utf-8. Bestandsuploads gebruikenmultipart/form-data; CSV-exports geventext/csvterug. Ongeldige UTF-8 wordt geweigerd met400 validation_failed. - Tijdstempels zijn ISO-8601 in UTC met millisecondenprecisie:
2026-04-20T14:23:45.123Z. Bij invoer wordt elke ISO-8601-offset geaccepteerd en naar UTC genormaliseerd. - Identificatoren zijn ondoorzichtige ULID’s of UUID’s. Er zijn geen numerieke ID’s, en e-mailadressen of telefoonnummers komen nooit in een URL voor.
Tenantisolatie en rechten
Section titled “Tenantisolatie en rechten”Elk geauthenticeerd verzoek draait binnen één account. Een resource die bij een ander account hoort, of bij een site die de rol van de aanroeper niet dekt, antwoordt met 404 not_found in plaats van 403, zodat nooit uitlekt of records bestaan. Een geldig token zonder het vereiste recht (bijvoorbeeld contacts.delete) antwoordt met 403 forbidden. Sommige rechten hebben een scope-achtervoegsel (conversations.read:own, :team, :all) dat beperkt wat een lijst teruggeeft.
PATCH accepteert alleen beschrijfbare velden. id, account_id, created_at, updated_at en statusvelden zoals resolved_at zijn alleen-lezen; stuur je er een mee, dan krijg je 400 validation_failed met details.forbidden_fields. Statuswijzigingen lopen via aparte acties zoals POST /tickets/:id/resolve.
Elke schrijfactie wordt vastgelegd in het auditlogboek van het account.
Headers voor observeerbaarheid
Section titled “Headers voor observeerbaarheid”Elke response bevat:
X-Request-Id: req_01HK…Log X-Request-Id. Daar vraagt support als eerste om.
De origin van het browserdashboard is https://app.rolchat.com. Openbare widgetendpoints staan elke origin toe, of alleen de origins die je voor een site verifieert. Aanroepen van server naar server met een API-sleutel vallen niet onder CORS.
Uitfasering
Section titled “Uitfasering”- De wijziging wordt aangekondigd in het wijzigingslogboek en het betreffende endpoint gaat
Deprecation: trueen eenSunset-header met de verwijderdatum meesturen. - Openbare endpoints blijven na de aankondiging nog minstens zes maanden werken.
- Verwijderen gebeurt alleen in een nieuwe hoofdversie. Binnen
v1zijn wijzigingen alleen aanvullend.
Gezondheid
Section titled “Gezondheid”Elke service biedt /healthz (liveness) en /readyz (readiness).