Errors
One envelope, a stable slug, a readable sentence, a request id.
HTTP/1.1 422 Unprocessable Entity
X-Request-Id: 2b7a…
{
"error": {
"type": "validation_error",
"message": "The request body is not valid",
"request_id": "2b7a…",
"fields": [{"field": "to.number", "message": "must be an E.164 phone number, like +15145550100"}]
}
}
Test error.type, never the text of message: the sentence may change, the slug will not. request_id is also the X-Request-Id header, present on every response, successful or not.
| type | HTTP | Meaning |
|---|---|---|
invalid_request | 400 | Something in the request is wrong: a bad parameter, an expired sync token, a bad cursor |
unauthorized | 401 | The token is missing, unknown, expired or revoked |
forbidden | 403 | The token is valid but may not do this (a client-credentials token on a "me" route, a suspended app) |
insufficient_scope | 403 | The token lacks the scope this route needs; WWW-Authenticate names it |
not_found | 404 | No such object, or not visible to this token |
conflict | 409 | The change collides with the current state (a number already assigned, a duplicate) |
validation_error | 422 | The body does not validate; fields lists each problem |
rate_limited | 429 | Over the tier's limit; wait Retry-After seconds |
server_error | 500 | Our fault. Quote request_id when you write to us |
The one exception: POST /oauth/token answers in the RFC 6749 shape ({"error": "invalid_grant", "error_description": "…"}, or invalid_client, invalid_scope, unsupported_grant_type), because OAuth libraries expect it.
