An API error always arrives in the same document: an errors array and a meta object. The general structure is described in the response shape; this page covers the contents of each error entry and how to handle it.
The full inventory of codes, with the meaning of each one, lives in the error taxonomy.
Fields of an entry
{
"errors": [
{
"status": "422",
"code": "phone_not_verified",
"detail": "The phone number is not verified.",
"source": { "pointer": "/data/attributes/phone" },
"meta": { "masked_phone": "+52 55 ••••1234" }
}
],
"meta": {
"version": "1.57.0",
"api_version": "v1",
"request_id": "a1b2c3d4e5f6",
"datetime": { "timezone": "UTC", "format": "ISO 8601" }
}
}| field | presence | content |
|---|---|---|
code | Always | Stable snake_case identifier. It is the only field an integration should branch on |
status | Always | The HTTP code repeated as a string, so an error keeps its category when processed away from the response |
detail | Always | Human-readable text. Translated according to the Accept-Language header (es / en) |
source.pointer | Optional | Body field that caused the rejection, as a JSON Pointer (RFC 6901) |
meta | Optional | Extra context for the rejection: masked_phone, retry_after_seconds, limit |
What is stable and what is not
The code neither changes nor gets translated: it is the contract. The detail changes with the language and may be reworded between releases without notice, because it is text to be read, not compared.
An integration branching on detail works until someone requests the other language or a sentence is rewritten. It is the most common mistake when consuming this API, and the quietest: it does not fail in testing, it fails in production.
Several errors in one response
A validation 422 returns one entry per invalid field, each with its own source.pointer:
"errors": [
{ "status": "422", "code": "required", "detail": "The fecha field is required.",
"source": { "pointer": "/data/attributes/fecha" } },
{ "status": "422", "code": "invalid_clabe_checksum", "detail": "The control digit does not match.",
"source": { "pointer": "/data/attributes/cuenta_beneficiaria" } }
]The correct traversal covers the whole array. Reading only errors[0] hides the remaining fields that need fixing, and forces a retry cycle the response had already resolved in one.
Meaning of each HTTP code
| status | meaning in this API |
|---|---|
400 | Malformed request: invalid JSON, missing parameter, wrong format |
401 | Authentication is missing or the credentials are not valid |
403 | Authenticated, but without permission for that resource or action |
404 | The resource does not exist or is not visible to the account |
405 | Correct route with the wrong HTTP method |
409 | State conflict: idempotency in flight, or resource already in a terminal state |
410 | The resource existed and was deleted |
413 | The body exceeds the operation's cap |
422 | The request arrived correctly but failed a business validation |
429 | The rate limits were exceeded |
500 | Unexpected server failure |
502 | An external service — usually Banxico — is unresponsive or returns malformed data |
503 | Subsystem temporarily disabled or overloaded |
The 5xx codes and 429 are retryable; the remaining 4xx are not, because the request must be corrected before being repeated.
Diagnosis
Every error response includes meta.request_id. That value identifies the specific request in the system logs and is the data required to investigate an individual case.