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

# Errors

> The error format and the error codes of the API.

The API returns each error with the HTTP status and a body in the [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html) format. The content type is `application/problem+json`.

```json theme={null}
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "The call did not include a valid API key. Send the key in the Authorization header, in the format Bearer <key>.",
  "code": "unauthorized"
}
```

## Fields

| Field | What it contains |
| - | - |
| `type` | Always `about:blank`. |
| `title` | The phrase of the HTTP status, in English. |
| `status` | The HTTP status. |
| `detail` | The explanation of the error, in the language of the organization. The text can change. |
| `code` | The error code, in English. The code does not change in v1. |

Use the `code` to decide what your system does. Show the `detail` to a person.

## The language of the explanation

The `detail` and the `message` follow the language that the organization chose in QX: Portuguese (`pt-BR`) or English (`en`). The API knows the organization from the key. For that reason, the answers that leave before the key stay in Portuguese:

* the call without a valid key (`401`) and the IP address with too many invalid keys (`429 too_many_invalid_keys`);
* the errors that the API answers before it reaches the endpoint, such as `route_not_found`, `method_not_allowed`, `not_acceptable` and the `malformed_request` of a path or a query that the API cannot read.

The `code`, the `title` and the field names are always in English. A replay with the same `Idempotency-Key` returns the stored answer in the language of the first call.

## Validation error

The `422` response with the code `validation_failed` also has the `errors` list, with one item for each field with an error. The other `422` codes have one cause only, which the `code` already names, and they do not have the list.

| Field | What it contains |
| - | - |
| `field` | The name of the field. |
| `code` | The error code of the field, in English. |
| `message` | The explanation of the field error, in the language of the organization. |

## Request outside the contract

The API checks each request against the OpenAPI specification of this documentation. The check runs after the checks of the key, the subscription, the plan and the call limit. A refused request does not use a paid write. The API does not keep its response for the `Idempotency-Key`.

| What is outside the contract | Response |
| - | - |
| A parameter of the query, of the path or of a header, and a query parameter that the endpoint does not declare | `400` with the code `invalid_parameter`. The `detail` names the parameter. |
| A value of the body, and a body field that the contract does not have | `422` with the code `validation_failed`. The `errors` list has one item for each field. |
| The whole body or the content type | `400` with the code `malformed_request`. |

The `field` of a field inside another field uses a dot, such as `recipient.email`. A body that is not an object appears as `body`. The `code` of the field follows this table:

| `code` | When |
| - | - |
| `blank` | A required field is missing, or a list or an object is empty. |
| `unknown` | The field does not exist in the contract. |
| `invalid` | The value has the wrong type, the wrong format or the wrong value. For example, a number where the contract asks for text. |

Some rules do not fit in the contract, such as "send the `contact_id` or the `tax_id`". The API checks these rules after the contract. So a request with both kinds of error gets the contract errors first.

## A call that the API cannot read

The `400` response with the code `malformed_request` tells that the API could not read the call. Examples of causes:

* the path or the query has an invalid encoding;
* the query repeats a parameter in different forms, such as `limit=1&limit[]=2`;
* the body is not valid JSON;
* the content type is not one of the types that the endpoint accepts, such as `text/plain` in a `POST` that receives JSON;
* the address in the `Client-IP` header is not in the `X-Forwarded-For` header.

## Codes

| Status | `code` | What to do |
| - | - | - |
| 400 | `invalid_parameter` | Correct the parameter that the `detail` names. |
| 400 | `malformed_request` | Check the path, the query, the body and the headers. The section "A call that the API cannot read" gives examples of causes. |
| 401 | `unauthorized` | Check the key and the `Authorization` header. |
| 402 | `subscription_blocked` | Settle the subscription in QX. |
| 402 | `trial_limit_reached` | Subscribe to a plan in QX. The organization on trial reached the document limit of the trial. |
| 403 | `organization_archived` | Talk to QX. |
| 403 | `plan_required` | Subscribe to a paid plan in QX. |
| 404 | `not_found` | Check the id. An id of another organization also gets `404`. |
| 404 | `route_not_found` | Check the path and the HTTP method. The API does not have the path, or the path does not accept the method. |
| 405 | `method_not_allowed` | Use an HTTP method that this documentation shows. The API does not recognize the method of the call. |
| 406 | `not_acceptable` | Check the `Content-Type` and `Accept` headers. The API does not recognize the content type of the call. |
| 409 | `contact_exists` | Use the contact in the `contact` field. The organization already has a contact with this CPF or CNPJ. |
| 409 | `idempotency_key_in_use` | Wait a few seconds and repeat the call with the same `Idempotency-Key`. See [Idempotency](/en/idempotency). |
| 409 | `document_has_content` | Check the document in QX. The Triage document already has a file or an answer, and the API swaps the file only on a collection document. |
| 409 | `document_locked` | Check the document in QX. The document is approved or discarded, or its collection does not accept documents. |
| 409 | `document_replaced` | Use the id in the `replaced_by` field. The document is a previous version, and the field contains the id of the current document. |
| 409 | `stale` | Call again. If the call included an `Idempotency-Key`, use a new value, because the API keeps this response. The data changed during the call. The call created no document and no collection. See [Idempotency](/en/idempotency). |
| 413 | `file_too_large` | Send a smaller file. The limit is 25 MB, and 10 MB for a type without a file field. |
| 422 | `validation_failed` | Correct the fields in the `errors` list. |
| 422 | `contact_not_found` | Create the contact with `POST /contacts` and repeat the call. |
| 422 | `contact_archived` | Restore the contact in QX, or use another contact. |
| 422 | `pack_unavailable` | Choose an active pack. The `active` field of `GET /packs` shows an active pack. |
| 422 | `pack_not_for_contact` | Choose a pack that serves the type of the contact. The `required_for` field of the pack shows the type. |
| 422 | `no_email` | Add the email of the contact in QX, or create the collection with `send_invitation` equal to `false`. |
| 422 | `shareholder_tree_too_large` | Talk to QX. The pack asks for a document from each shareholder. The shareholder tree of the contact has more than 200 people and companies. The tree includes the contact. |
| 422 | `contact_mismatch` | Send the document of the collection's contact, or send the document without `collection_id`. |
| 422 | `collection_not_accepting` | Choose an open collection. The collection is canceled, archived or with the partner, or it has no contact yet. |
| 422 | `document_type_inactive` | Choose an active document type. |
| 422 | `document_type_without_file` | Choose a type that accepts a file. The type is a form without a file field. |
| 422 | `unsupported_file` | Send the file in a format that the type accepts. A type without a file field accepts only PDF, JPEG and PNG. |
| 422 | `unknown_field` | Use the `key` of a field that `GET /documents/{id}` shows. |
| 422 | `idempotency_key_reused` | Use a new `Idempotency-Key` value for the new write. See [Idempotency](/en/idempotency). |
| 429 | `rate_limited` | Wait for the seconds in the `Retry-After` header. |
| 429 | `daily_limit_reached` | Wait for the seconds in the `Retry-After` header. The limit resets at midnight, in the time zone of the organization. |
| 429 | `too_many_invalid_keys` | Correct the key and wait for the seconds in the `Retry-After` header. |
| other 4xx | `request_refused` | Talk to QX. The API could not complete the call. |
| 503 | `storage_unavailable` | Repeat the call in a few seconds, with the same `Idempotency-Key`. QX did not store the file, and the API created no document. |
| 5xx | `internal_error` | Repeat the call in a few seconds. On a write that accepts the `Idempotency-Key`, repeat the call with the same value. See [Idempotency](/en/idempotency). If the error continues, talk to QX. QX had an internal error. |
