Skip to content

Errors and limits

Every refusal is application/problem+json:

{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"code": "bad_request",
"detail": "`attributes.plan` should be a string, not a number",
"request_id": "01JA...",
"errors": [{ "field": "attributes.plan", "message": "should be a string, not a number" }]
}

Switch on code, never on detail: detail is a sentence for people and may be reworded. Quote request_id when asking for help. A 400 names the field that is wrong in errors, such as attributes.plan, events.2.name or external_id, and suggests the right name for a field it does not know.

StatusCodeWhat to do
400bad_requestFix the request: the problem names the field.
400app_key_requiredSend X-CRM-App-Key.
401unauthorizedThe key or token is wrong, revoked or for another app; the detail says which. Asking again will not help.
401token_expiredGet a fresh token from your backend, and ask once more.
403app_unavailableThe app is archived or deleted. Stop sending until it is restored.
404not_foundNot there, or the part is switched off for the app.
409erasedThe person was erased lately: nothing new is kept about them.
409refusedNot possible as things stand: the detail says why.
409rating_closed, survey_closed, bot_moved_onThat moment has passed: read the conversation or survey again.
413The body is too large.
422attachment_invalid, answer_invalidA picture or an answer that is not right.
429rate_limitedToo many requests: wait for Retry-After seconds.
503unavailableNot set up yet, or briefly down. Try again later.
WhatLimit
Server API, per key1,200 requests a minute.
Server API events500 a request.
Event definitions500 a request; 250 events of your own an app.
Server keys20 an app.
Guest API, per user30 event batches and 120 other requests a minute.
Guest events50 a batch.
Public routes, per addressAbout 120 requests a minute.
Webhook endpoints20 an app.
New attributes and events on first sight50 a day an app.
Identity tokensAt most 30 days long.

Past a limit, the answer is 429 with Retry-After. Spread a backfill over time so your live traffic keeps room.