Ga naar inhoud

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.

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).

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.

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.

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=50
GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…
  • limit is standaard 50 en maximaal 200; grotere waarden worden geweigerd met 400 validation_failed.
  • Cursors zijn ondoorzichtig en verlopen na 24 uur (400 validation_failed met code: 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 met rel="next" en rel="prev" meegestuurd.

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.

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: 1000
X-RateLimit-Remaining: 543

Overschrijd 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.

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.

  • Verzoeken en responses zijn application/json; charset=utf-8. Bestandsuploads gebruiken multipart/form-data; CSV-exports geven text/csv terug. Ongeldige UTF-8 wordt geweigerd met 400 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.

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.

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.

  1. De wijziging wordt aangekondigd in het wijzigingslogboek en het betreffende endpoint gaat Deprecation: true en een Sunset-header met de verwijderdatum meesturen.
  2. Openbare endpoints blijven na de aankondiging nog minstens zes maanden werken.
  3. Verwijderen gebeurt alleen in een nieuwe hoofdversie. Binnen v1 zijn wijzigingen alleen aanvullend.

Elke service biedt /healthz (liveness) en /readyz (readiness).