> ## Documentation Index
> Fetch the complete documentation index at: https://docs.origoid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Common error types and how to handle them.

OrigoID never returns opaque errors. Every error includes:

* A **stable `type` code** that does not change between versions
* A **human `message`** describing what happened
* An actionable path to resolution

## Common error types

| `type`                | HTTP | What it means                                 | What to do                                                                           |
| --------------------- | ---- | --------------------------------------------- | ------------------------------------------------------------------------------------ |
| `INVALID_REQUEST`     | 200  | Your request body did not pass validation     | Inspect `errors[]`, fix the listed fields, retry                                     |
| `UNAUTHORIZED`        | 401  | Authentication failed                         | Verify your API key. Check your IP allow-list. If you suspect a leak, rotate.        |
| `RATE_LIMIT_EXCEEDED` | 429  | You exceeded your rate limit                  | Implement exponential backoff. Consider upgrading your plan.                         |
| `SERVICE_UNAVAILABLE` | 200  | An upstream source is temporarily unavailable | Retry with backoff. Check [status.origoid.com](https://status.origoid.com)           |
| `INTERNAL_ERROR`      | 200  | An unexpected error occurred                  | Save the `transactionId` and email [support@origoid.com](mailto:support@origoid.com) |

## Endpoint-specific result codes

Each endpoint can return additional `type` codes that represent valid business results (not errors per se). For example:

* CURP endpoints can return `CURP_NOT_FOUND`, `CURP_APOCRYPHAL`, `CURP_DECEASED`
* SAT endpoints can return `CFDI_CANCELED`, `TAX_PROFILE_NOT_FOUND`
* Voter ID endpoints can return `INE_NOT_FOUND`, `INE_NOT_VALID`
* Biometric endpoints can return `FACE_MISMATCH`, `MASK_ATTACK`

The complete list of `type` codes for each endpoint is documented in that endpoint's page in the [API reference](/en/api-reference). Treat business results according to your domain logic.

## Validation error codes

When `type` is `INVALID_REQUEST`, the `errors[]` array lists field-level failures (see [ErrorDetail](/en/envelope#errordetail-entries-in-errors)). Each entry has a `code` you can branch on.

These codes are **cross-cutting** — they may appear on any endpoint when the corresponding validation fails:

| `code`                    | When it appears                                                                                                                                                                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MALFORMED_JSON`          | The request body is not valid JSON. The `field` is `body`.                                                                                                                                                                           |
| `PAYLOAD_TOO_LARGE`       | Either the whole request body exceeds 28 MB (`field: "body"`), or a base64 image/PDF field exceeds 12 MB (`field: "<field name>"`).                                                                                                  |
| `MISSING_REQUIRED_FIELD`  | A required field is absent.                                                                                                                                                                                                          |
| `MISSING_DEPENDENT_FIELD` | A field that depends on another required field is missing (e.g. `cif` provided without `rfc`).                                                                                                                                       |
| `INVALID_TYPE`            | A field has the wrong primitive type (e.g. number where string is expected).                                                                                                                                                         |
| `INVALID_FORMAT`          | A field does not match its required pattern or format (CURP, RFC, NSS, ISO dates, base64, etc.).                                                                                                                                     |
| `INVALID_ENUM_VALUE`      | A field's value is not in the allowed enum. See [Catalogs](/en/catalogs).                                                                                                                                                            |
| `INVALID_LENGTH`          | A string is shorter or longer than allowed.                                                                                                                                                                                          |
| `OUT_OF_RANGE`            | A numeric value is outside its allowed range.                                                                                                                                                                                        |
| `INVALID_ARRAY`           | An array has too few/many items, or duplicates that are not allowed.                                                                                                                                                                 |
| `UNKNOWN_FIELD`           | The body contains a field the endpoint does not recognize.                                                                                                                                                                           |
| `SCHEMA_MISMATCH`         | The body does not satisfy a `oneOf` / `anyOf` constraint — specifically, all alternatives were provided when only one was allowed. When some alternatives are missing, you receive `MISSING_REQUIRED_FIELD` per alternative instead. |
| `INVALID_SCOPE`           | The requested OAuth scope is not granted to the API key. Returned by `/auth/token` when the caller asks for scopes outside its grant.                                                                                                |
| `INVALID_VALUE`           | A value is invalid for reasons not covered above (typical fallback).                                                                                                                                                                 |

### Endpoint-specific codes

Some endpoints add extra codes that capture domain-specific validation. For example:

* `INVALID_RFC_FORMAT` (`/mex/fiscal/v1/rfc-validations`, SAT 69 / 69-B searches)
* `NAME_TOO_SHORT`, `NAME_ONLY_STOPWORDS` (SAT 69 / 69-B searches)
* `QR_NOT_FOUND` (`/mex/fiscal/v1/csf-extractions`, `/mex/fiscal/v1/cfdi-validations`)
* `IMAGE_UNREADABLE` (OCR endpoints)

See each operation's page in the [API reference](/en/api-reference) for the full list.

### How errors aggregate

Multiple field-level validation failures in the same request may come back together in `errors[]`. The array length depends on which kind of validation failed:

* Failures detected by request-shape validation (missing required fields, wrong types, bad patterns, enum / length / range mismatches) are **aggregated** — all violations of this kind come back in one response.
* Failures detected by domain-specific checks (e.g. `INVALID_RFC_FORMAT`, `NAME_TOO_SHORT`, `QR_NOT_FOUND`) may return only the **first** error encountered, even if other fields would also have failed.

Always iterate `errors[]` rather than assuming a single entry. If your code receives one error, fixes it, and resubmits, the next response may surface additional errors that were latent.

## Reporting an issue

If you hit an unexpected error, email [support@origoid.com](mailto:support@origoid.com) with:

* The `transactionId` from the response
* A brief description of what you were trying to do
* The endpoint you called

<Note>
  We do not log request or response bodies, so we cannot retrieve your call automatically. When reporting, please include the `transactionId` and the path you called, and we will work with you on next steps.
</Note>
