# Errors

Every error is a problem object, under `error`:

```json
{ "error": { "code": "not_found", "message": "No such car type, or nothing prices it." } }
```

The `code` is stable and meant for your program. The `message` is for a person and may change.

| Status | Code                   | When                                                                                                                                                                                                 |
| ------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401    | `unauthorized`         | No key, a wrong key, or a revoked key.                                                                                                                                                               |
| 403    | `forbidden`            | The key's scopes do not cover the call. Every path answers this way.                                                                                                                                 |
| 403    | `paused`               | The rental paused this channel. Its key reads bookings, but gets no offers or quotes and holds, makes, changes or cancels nothing.                                                                   |
| 404    | `not_found`            | No such rental, car type, location, booking or affiliate on this key. Another channel's booking is a 404, not a 403.                                                                                 |
| 409    | `none_free`            | No car free for that car type over those days.                                                                                                                                                       |
| 409    | `class_locked`         | The car is out, so the car type cannot change.                                                                                                                                                       |
| 409    | `wrong_status`         | The booking is not reserved. A key changes or cancels a booking only while reserved. Later, the rental makes changes.                                                                                |
| 409    | `manual_price`         | The rental priced the booking by hand, so only the rental changes it.                                                                                                                                |
| 409    | `below_paid`           | The change drops the total below what is paid. A refund is the rental's decision.                                                                                                                    |
| 409    | `in_progress`          | The same `Idempotency-Key` is still being handled. Retry in a moment.                                                                                                                                |
| 409    | `idempotency_mismatch` | The `Idempotency-Key` was used before with a different body.                                                                                                                                         |
| 409    | `no_processor`         | The rental takes no online payments, or its processor cannot be reached.                                                                                                                             |
| 409    | `no_return_url`        | A payment link needs a return address, and neither the request nor the rental has one.                                                                                                               |
| 409    | `processor`            | The payment processor refused. The message is the processor's.                                                                                                                                       |
| 409    | `code_taken`, `member` | Another affiliate has that code, or that email is already in the program.                                                                                                                            |
| 409    | `not_open`             | `reject` on a commission that is `paid`, `void` or `reversed`. On the manage booking routes: the booking cannot change any more. `PATCH` and `cancel` never answer this: they answer `wrong_status`. |
| 422    | `invalid`              | A field is missing or wrong. The message says which.                                                                                                                                                 |
| 422    | `quote`                | The booking cannot be priced. The message names the quote's problem.                                                                                                                                 |
| 422    | `driver_too_young`     | The driver is under the car type's minimum age, on a quote, a booking or a change of car type.                                                                                                       |
| 429    | `rate_limited`         | The key made more than 600 calls in a minute. Wait the seconds in `Retry-After`, then call again. Every key alike.                                                                                   |
| 500    | `internal`             | Something went wrong on our side. See the retry rule below.                                                                                                                                          |

## A 500 and the Idempotency-Key

A `500` on `POST /rentals/{slug}/bookings` (or the reseller's `POST /bookings`) can come after the API took the `Idempotency-Key`. The key then stays in progress for 24 hours. A retry with the same key answers `409` with `in_progress` for that time. It does not give the first answer again.

Thus a retry with the same key cannot tell you if the booking was made. Read your bookings first, with `GET /rentals/{slug}/bookings` or the reseller's `GET /bookings`. When the booking is not there, send it again with a new `Idempotency-Key`.

A booking that cannot be written can also answer `422` with the code of what is wrong with it, such as `no_class`, `bad_location` or `not_sold`.

A quote with a problem is not an error: it answers `200` and lists the problems in `problems`. [Making a booking](/bookings) lists them.
