# Errors (https://docs.loybox.com.ar/en/api-reference/errores)



When something goes wrong, the API responds with an HTTP status code and a body
with a single field:

```json
{
  "message": "Client not found"
}
```

The `message` is text for the developer, not for showing to the user: it can
change without notice. What your code should look at is **the status code**.

## Status codes
| Code  | What it means                                                                                                       | What to do                                                                                                                  |
| ----- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `200` | It worked.                                                                                                          | —                                                                                                                           |
| `201` | The resource was created. Both [Consumptions](https://docs.loybox.com.ar/api-reference/consumos) endpoints return this.                       | —                                                                                                                           |
| `400` | The request could not be processed: the benefit was already used, it is not valid, or the user's points fall short. | Read the `message` to know which case it is. Do not retry as is.                                                            |
| `401` | The credential is missing, expired, or does not work for this endpoint.                                             | With an API key, check it is the right one. With an end-user token, [renew it](https://docs.loybox.com.ar/api-reference/autenticacion/renovar-token). |
| `403` | The client exists but cannot have consumptions.                                                                     | Do not retry.                                                                                                               |
| `404` | The resource does not exist: client, benefit or commerce.                                                           | Check the code or the id you sent.                                                                                          |
| `422` | The body or the headers failed validation.                                                                          | See [Validation errors](#errores-de-validación).                                                                            |

## Validation errors
The `422` is different from the rest: it does not carry a `message` but a `detail`
with the list of everything that is wrong, one item per field.

```json
{
  "detail": [
    {
      "loc": ["body", "amount"],
      "msg": "Input should be a valid integer",
      "type": "int_parsing"
    }
  ]
}
```

<Fields title="Each item of detail">
  <Field name="loc" type="array" required="true">
    Where the problem is. The first element says which part of the request
    (`body`, `query`, `header`, `path`) and the rest is the path to the field.
  </Field>

  <Field name="msg" type="string" required="true">
    What is wrong with it.
  </Field>

  <Field name="type" type="string" required="true">
    The kind of validation error.
  </Field>
</Fields>

The most frequent cause of a `422` is not the body: it is **the missing
`X-Commerce-Id` header**. It is required on every endpoint of
[Authentication](https://docs.loybox.com.ar/api-reference/autenticacion),
[My account](https://docs.loybox.com.ar/api-reference/mi-cuenta) and [Public](https://docs.loybox.com.ar/api-reference/publico).

## Two cases that are not errors
<Callout title="Requesting a code always answers 200">
  [`POST /v1/auth/otp/request`](https://docs.loybox.com.ar/api-reference/autenticacion/pedir-codigo) answers
  `200` even if the email has no Loybox account. That is deliberate: if it answered
  differently, anyone could use the endpoint to find out which emails are
  registered. Do not use it to check whether a user exists.
</Callout>

<Callout title="No tier assigned is a 404">
  [`GET /v1/me/level`](https://docs.loybox.com.ar/api-reference/mi-cuenta/nivel) returns `404` when the user
  does not have a tier yet, or when the commerce does not use tiers. It is the
  normal case for a new member, not a failure: in the UI the right move is to hide
  the tiers section, not to show an error.
</Callout>

## Retries
Buying a benefit moves points, so a blind retry can charge them twice. That is
what [`POST /v1/me/benefits/exchange`](https://docs.loybox.com.ar/api-reference/mi-cuenta/comprar-beneficio)
accepts the `Idempotency-Key` header for: if you send the same value again, the
purchase does not repeat.

```
Idempotency-Key: 8f14e45f-ea0f-4d1c-9a1b-2c3d4e5f6a7b
```

Use a different value for each purchase the user starts (a UUID is enough) and the
same one across every retry of that purchase.
