The CRM’s API uses standard HTTP status codes with a small, consistent JSON error shape:
{ "error": "short_machine_code", "message": "Human-readable explanation." }The ones you’ll see most
| Status | What it means |
|---|---|
| 400 | The request body or query failed validation. The message will tell you which field. |
| 401 | No token, or the token didn't validate against the Platform's public key. Sign in again. |
| 403 | You're authenticated but not authorised for this resource — wrong Client, wrong role, or wrong tenant. |
| 404 | The resource doesn't exist or is in a Client you don't have access to. Both look the same from the outside. |
| 409 | Conflict — usually a uniqueness violation. Most commonly hit on activity dedup when a webhook retries. |
| 410 | A WhatsApp config has been soft-disabled. Meta will retry; once it backs off the warnings stop. |
| 422 | Business-rule rejection. E.g. trying to subscribe to MCP without the CRM — the dependency check fires here. |
| 429 | Rate limit. Back off and retry; the response includes a Retry-After header. |
| 500 | Something blew up server-side. Check the API logs; include the request id when you file a bug. |
Where the API needs more detail than the message can carry — like which fields failed validation — the response carries adetailsobject alongsideerrorandmessage.