Error catalog
Every v3 failure is a JSON object with a machine-readable code and a human-readable message, both nested under error. This page goes code by code: what it most likely means, and what to check first.
Looking for retry and rate-limit behavior?
The v3 and 2.1 envelopes compared side by side, plus the shared rate limits, are covered on the errors and retries concept page. This page is the code-by-code lookup. Errors, retries and rate limits
The error envelope
Every v3 failure takes this shape:
json
{
"error": {
"code": "NOT_FOUND",
"message": "Container not found"
}
}
Codes
One row per code — what most likely caused it, and what to fix.
| Code | Likely cause | Fix |
|---|---|---|
| NOT_FOUND | The crid, message id, or other resource in the path does not exist. | Confirm the identifier you sent — a typo or a stale crid is the usual cause. |
| NO_MESSAGE | The container exists, but no message has been recorded against it yet. | Wait for the recording to complete, or check that the widget successfully attached a message to this crid. |
| MESSAGE_MISSING | The operation you called requires a recorded message, and none exists. | Same root cause as NO_MESSAGE, on an operation that cannot proceed without one — confirm recording completed before calling it. |
| DATA_INVALID | The request body does not match the shape the endpoint expects. | Check required fields and types against the reference for this operation, including nested objects like sender or recipient. |
| EMPTY_UPDATE | A PATCH request was sent with no field to update. | Include at least one field in the request body — an empty or fully-omitted body is rejected rather than treated as a no-op. |
| VALIDATION_ERROR | The request failed validation for a reason not covered by DATA_INVALID — often a value outside an allowed range or enumeration. | Read the message field for the specific rule that failed; it names the field. |
| FORBIDDEN | The key authenticated, but is not scoped or platform-constrained for this request. | Check the key's scopes and platform constraint — the key itself is valid, it is just not allowed to do this. |
| UNAUTHORIZED | The key is missing, unknown, expired, or revoked. | Confirm the Authorization header is present and correctly formed, then check the key's status in the client portal. |
What is safe to replay
Not every call can be retried with the same confidence.
- Container creation is idempotent on the crid you supply — replaying it returns the existing container's links without creating a second one or mutating it.
- notify and unlock are not idempotent — replaying either one re-triggers its effect, rather than returning the same result harmlessly.