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

# Erreurs

Toute réponse `4xx` ou `5xx` est un objet RFC 9457 (`application/problem+json`) :

```json theme={null}
{
  "type": "https://api.lexio.rent/errors/rental-busy",
  "title": "Location occupée",
  "status": 409,
  "code": "RENTAL_BUSY",
  "detail": "Une autre opération est en cours sur cette location.",
  "instance": "/api/external/v1/rentals/9c2d7e4a-5b1f-4d3c-8a6e-0f1b2c3d4e5f/cancel",
  "requestId": "9b2d6c1e-4f3a-4e8b-a1d7-3c5e9f0a2b46"
}
```

* `code` : la référence stable, à tester dans votre code. Le catalogue ci-dessous est extensible : un code inconnu se traite selon son statut HTTP.
* `title` et `detail` : textes en français pour un humain ; ils peuvent changer, ne les interprétez pas par programme.
* `type` : URI stable propre au code. Ouverte dans un navigateur, elle mène à ce guide.
* Membres supplémentaires (`reasons`, `conflictingId`, `expectedTotalTTC`…) : propres à chaque code, listés après « Champs : » dans le catalogue.
* `errors[]` accompagne les refus de champs : chaque élément porte un `pointer` (RFC 6901 : `/startAt`, `/options/0/optionId`), un `code` stable et un `detail`.
* `requestId` : identifiant de la requête, aussi dans l’en-tête `X-Request-Id`. Joignez-le à toute demande à [contact@lexio.rent](mailto:contact@lexio.rent).
* `Retry-After` (secondes) accompagne les codes qu’on peut renvoyer tels quels (« Rejouable après `Retry-After` » dans le catalogue). Les autres ne réussiront pas à l’identique, sauf `500` (voir [Idempotence et reprise](https://docs.lexio.rent/idempotence.md)).

Une opération ne répond que par les codes qu’elle déclare dans la référence, plus un socle commun (clé, scope, plan, débit, validation, erreur interne). Un même refus porte le même statut et le même code sur toutes les opérations.

## Que faire selon le statut

| Statut | Signification | Votre réaction |
| - | - | - |
| `400` | requête mal formée : JSON, type, format, champ inconnu ou manquant | corriger la requête |
| `401` | clé absente, invalide, désactivée, révoquée ou expirée | selon le `code` : voir [Authentification et scopes](https://docs.lexio.rent/authentification.md) |
| `403` | scope manquant, organisation suspendue, fonctionnalité hors plan | demander au loueur la clé ou le plan nécessaire |
| `404` | ressource inexistante, ou hors du périmètre de la clé | ne pas réessayer |
| `405`, `413`, `415` | méthode, taille ou type de contenu | corriger la requête |
| `409` | l’état d’une ressource empêche l’opération (statut de la location, devis déjà utilisé, doublon, écriture concurrente) | relire la ressource ; ne renvoyer que les codes à `Retry-After` |
| `410` | curseur d’événements expiré | resynchroniser : voir [Synchronisation par événements](https://docs.lexio.rent/synchronisation.md) |
| `422` | requête bien formée, refusée par une règle du loueur ou des données (référence, règle de réservation, plafond, montant) | changer les données |
| `429` | débit dépassé | attendre `Retry-After` |
| `500`, `503` | incident, ou service tiers indisponible | renvoyer avec la même `Idempotency-Key`, après `Retry-After` si présent (quelques secondes pour un `500`) |

## Catalogue des codes

| Code | Signification | Que faire |
| - | - | - |
| `MALFORMED_REQUEST` · 400 | Corps de requête illisible | Envoyez un JSON UTF-8 valide : vérifiez l’échappement et l’encodage du corps. |
| `VALIDATION_FAILED` · 400 | Requête invalide | Corrigez les champs désignés par `errors[]` (`pointer`, `code`), puis renvoyez. Champs : `errors[]`. |
| `API_KEY_DISABLED` · 401 | Clé API désactivée | Demandez au loueur de réactiver la clé dans Lexio : la même clé refonctionnera. |
| `API_KEY_EXPIRED` · 401 | Clé API expirée | Demandez une nouvelle clé au loueur ; anticipez avec `apiKey.expiresAt` de `GET /organization`. |
| `API_KEY_INVALID` · 401 | Clé API invalide | Vérifiez la forme de l’en-tête et la clé copiée ; une clé perdue ne se retrouve pas, le loueur en crée une autre. |
| `API_KEY_MISSING` · 401 | Clé API absente | Ajoutez l’en-tête `Authorization: Bearer lck_…`. |
| `API_KEY_REVOKED` · 401 | Clé API révoquée | Demandez une nouvelle clé au loueur. |
| `FEATURE_NOT_AVAILABLE` · 403 | Fonctionnalité non incluse | Le plan du loueur n’inclut pas la fonctionnalité `feature` : voir la table des fonctionnalités du guide Authentification. Champs : `feature`. |
| `INSUFFICIENT_SCOPE` · 403 | Scope insuffisant | Demandez au loueur une clé qui porte l’un des `requiredScopes` : une clé existante ne gagne pas de scope. Champs : `requiredScopes`. |
| `ORGANIZATION_SUSPENDED` · 403 | Organisation suspendue | Le loueur doit régulariser son abonnement Lexio ; ne réessayez pas d’ici là. |
| `NOT_FOUND` · 404 | Ressource introuvable | Vérifiez l’identifiant ; une clé partenaire ne voit que ses propres locations, devis et clients. Ne réessayez pas. Champs : `resource`. |
| `ROUTE_NOT_FOUND` · 404 | Route inconnue | Vérifiez le chemin et l’adresse de base `/api/external/v1`. |
| `METHOD_NOT_ALLOWED` · 405 | Méthode non autorisée | Utilisez l’une des méthodes de `allowed`. Champs : `allowed`. |
| `ALREADY_EXISTS` · 409 | Doublon | Une ressource porte déjà cette valeur (`field`) : relisez `conflictingId` au lieu de recréer. Champs : `field`, `conflictingId`. |
| `BOOKING_REFUSED` · 409 | Réservation refusée | Le loueur n’accepte pas cette réservation ; ne réessayez pas pour ce client. |
| `CREDIT_NOTE_NOT_ISSUABLE` · 409 | Avoir impossible à émettre | L’avoir est refusé à l’émission ; `detail` en donne la cause (fiche entreprise du loueur incomplète, avoir en brouillon déjà ouvert…). Le loueur la règle dans Lexio, puis renvoyez. |
| `CUSTOMER_ANONYMIZED` · 409 | Client anonymisé | La fiche est anonymisée et figée : utilisez une autre fiche client. |
| `CUSTOMER_BLOCKED` · 409 | Client bloqué | Le loueur a bloqué ce client ; la décision se prend dans Lexio. |
| `DEFAULT_ITEM_REQUIRED` · 409 | Élément par défaut requis | Désignez d’abord un autre élément par défaut, puis modifiez, désactivez ou supprimez celui-ci. |
| `IDEMPOTENCY_ALREADY_APPLIED` · 409 | Écriture déjà appliquée | L’écriture est faite : ne renvoyez pas, relisez la ressource `resourceId` (en-tête `Location` quand elle se relit par un `GET`). Champs : `resourceId`. |
| `IDEMPOTENCY_IN_FLIGHT` · 409 | Requête identique en cours | La même requête est en cours : renvoyez à l’identique après `Retry-After`. Rejouable après `Retry-After`. |
| `INVOICE_FINALIZED` · 409 | Facture finalisée | Une facture émise fige ce point : la correction se fait dans Lexio. |
| `MAINTENANCE_TRACKING_ALREADY_STARTED` · 409 | Suivi d’entretien déjà démarré | Le suivi d’entretien est déjà démarré ; sa réinitialisation se fait dans Lexio. Champs : `maintenanceTrackingMode`. |
| `MAINTENANCE_TRACKING_NOT_STARTED` · 409 | Suivi d’entretien non démarré | Démarrez le suivi d’entretien du véhicule (`maintenanceTrackingMode` de `PATCH /vehicles/{vehicleId}`). |
| `OPTION_UNAVAILABLE` · 409 | Option en rupture | Stock insuffisant (`availableQuantity`) : réduisez la quantité ou retirez l’option. Champs : `optionId`, `availableQuantity`. |
| `OVERPAYMENT_RESOLUTION_REQUIRED` · 409 | Trop-perçu à résoudre | Renvoyez avec `overpaymentResolution` (scope `payments.refund`) ; si `resolvableByKey` est faux, le loueur traite la baisse dans Lexio. Champs : `overpaidAmount`, `resolvableByKey`. |
| `PAYMENT_PROVIDER_MANAGED` · 409 | Paiement géré par le prestataire | Paiement encaissé chez Stripe : le remboursement se fait chez Stripe, et Lexio l’enregistre à réception de l’événement Stripe. |
| `PRICE_CHANGED` · 409 | Prix modifié | Le prix a changé (`currentTotalTTC`) : redemandez un devis ou un aperçu, puis renvoyez avec le nouveau total. Champs : `expectedTotalTTC`, `currentTotalTTC`. |
| `QUOTE_ALREADY_USED` · 409 | Devis déjà utilisé | Le devis a déjà créé la location `rentalId` : relisez-la ; une autre réservation demande un nouveau devis. Champs : `rentalId`. |
| `QUOTE_EXPIRED` · 409 | Devis expiré | Demandez un nouveau devis. |
| `RANGE_OVERLAP` · 409 | Plages qui se chevauchent | La plage chevauche celle de `conflictingId` : ajustez les bornes de l’une ou de l’autre. Champs : `errors[]`, `conflictingId`, `minRentalDays`, `maxRentalDays`, `minLeadDays`, `maxLeadDays`. |
| `RENTAL_BUSY` · 409 | Location occupée | Une autre opération est en cours : renvoyez à l’identique après `Retry-After`. Rejouable après `Retry-After`. |
| `RENTAL_CHANGED` · 409 | Location modifiée entre-temps | La location a changé entre-temps : relisez-la, puis décidez. |
| `RENTAL_STATUS_NOT_ALLOWED` · 409 | Statut de la location incompatible | Relisez la location : l’`action` n’est possible que dans les `allowedStatuses` (guide Cycle de vie). Champs : `errors[]`, `rentalStatus`, `allowedStatuses`, `action`. |
| `RESOURCE_IN_USE` · 409 | Ressource utilisée | Rien n’est écrit : l’élément est encore utilisé (`blockers` : cause et nombre). La description de l’opération donne l’alternative (désactiver, archiver, annuler, faire anonymiser par le support Lexio). Champs : `blockers`. |
| `SEPA_DEBIT_PENDING` · 409 | Prélèvement SEPA en cours | Un prélèvement SEPA est en cours (`pendingDebitAmount`) : réessayez une fois réglé. Champs : `pendingDebitAmount`. |
| `VEHICLE_ARCHIVED` · 409 | Véhicule archivé | Désarchivez le véhicule avant de le modifier, ou choisissez-en un autre. |
| `VEHICLE_UNAVAILABLE` · 409 | Véhicule indisponible | Le véhicule n’est pas réservable sur la période (`reasons`, `conflicts`) : proposez une autre période ou un autre véhicule. Champs : `reasons`, `conflicts`, `overdueOperations`. |
| `CURSOR_EXPIRED` · 410 | Curseur expiré | Curseur d’événements trop ancien : resynchronisez (guide Synchronisation). |
| `PAYLOAD_TOO_LARGE` · 413 | Corps trop volumineux | Réduisez le corps sous `maxBytes` octets. Champs : `maxBytes`. |
| `UNSUPPORTED_MEDIA_TYPE` · 415 | Type de contenu non pris en charge | Envoyez le corps avec l’un des types de `accepted`. Champs : `accepted`. |
| `BOOKING_RULE_VIOLATION` · 422 | Règle de réservation non respectée | La période enfreint la règle `rule` du loueur : ajustez-la d’après `businessHours` et `bookingRules` de `GET /organization`. Champs : `errors[]`, `rule`. |
| `DISCOUNT_CAP_EXCEEDED` · 422 | Plafond de remise dépassé | Ramenez la remise à `maxDiscountPercent` au plus. Champs : `errors[]`, `maxDiscountPercent`. |
| `DRIVER_AGE_MISMATCH` · 422 | Âge du conducteur différent du devis | La date de naissance du titulaire contredit le devis (jeune conducteur) : redemandez un devis avec la bonne date. Champs : `errors[]`. |
| `IDEMPOTENCY_KEY_REUSED` · 422 | Clé d’idempotence réutilisée | Cette `Idempotency-Key` a servi à une autre requête : une clé par opération. |
| `OPTION_OUT_OF_SEASON` · 422 | Option hors saison | L’option n’est pas proposée sur ces dates : retirez-la. Champs : `errors[]`. |
| `OPTION_QUANTITY_EXCEEDED` · 422 | Quantité d’option dépassée | Ramenez la quantité à `maxQuantity` au plus. Champs : `errors[]`, `maxQuantity`. |
| `PAYMENT_EXCEEDS_DUE` · 422 | Encaissement supérieur au dû | Enregistrez au plus `dueAmount`, le reste à payer. Champs : `errors[]`, `dueAmount`. |
| `PAYMENT_NOT_VERIFIED` · 422 | Paiement non vérifié | Le PaymentIntent ne correspond pas à la location (`reason`) : voir le guide Intégration d’une plateforme de réservation. Champs : `errors[]`, `reason`. |
| `PRICING_CHOICE_NOT_AVAILABLE` · 422 | Choix tarifaire indisponible | Choisissez l’un des `availablePricingChoices`. Champs : `errors[]`, `availablePricingChoices`. |
| `PROMO_CODE_REJECTED` · 422 | Code promo refusé | Code promo refusé (`reason`) : retirez-le ou adaptez la réservation. Champs : `errors[]`, `reason`, `minRentalDays`. |
| `REFERENCE_INACTIVE` · 422 | Référence inactive | La référence pointée par `errors[]` est désactivée : choisissez-en une active. Champs : `errors[]`. |
| `REFERENCE_NOT_FOUND` · 422 | Référence introuvable | La référence pointée par `errors[]` n’existe pas, ou pas pour cette clé : relisez le catalogue. Champs : `errors[]`. |
| `REFUND_EXCEEDS_PAID` · 422 | Remboursement supérieur à l’encaissé | Remboursez au plus `maxRefundableAmount`. Champs : `errors[]`, `maxRefundableAmount`. |
| `UPLOAD_INVALID` · 422 | Téléversement invalide | Le fichier déposé est refusé (`errors[]`) : déposez un fichier conforme. Champs : `errors[]`. |
| `VAT_REVERSE_CHARGE_NOT_ALLOWED` · 422 | Autoliquidation impossible | Autoliquidation impossible (`reason`) : retirez `isVatReverseCharge` ou faites compléter le numéro de TVA manquant. Champs : `reason`. |
| `RATE_LIMITED` · 429 | Trop de requêtes | Attendez `Retry-After`, puis renvoyez à l’identique. Champs : `limit`, `windowSeconds`, `retryAfter`. Rejouable après `Retry-After`. |
| `INTERNAL_ERROR` · 500 | Erreur interne | Renvoyez avec la même `Idempotency-Key` après quelques secondes ; si l’erreur persiste, écrivez à [contact@lexio.rent](mailto:contact@lexio.rent) avec le `requestId`. |
| `SERVICE_UNAVAILABLE` · 503 | Service momentanément indisponible | Un service tiers (`dependency`) est indisponible : renvoyez après `Retry-After`. Champs : `dependency`. Rejouable après `Retry-After`. |

## Valeurs des champs énumérés

* `RESOURCE_IN_USE`, `blockers[].code` : `RENTALS`, `ACTIVE_RENTALS`, `INCIDENTS`, `CONTRAVENTIONS`, `MAINTENANCE_RECORDS`, `INSPECTIONS`, `VEHICLE_CHECKS`, `VEHICLE_BLOCKS`, `VEHICLES`, `DEPOSITS`, `DEDUCTIBLES`, `INVOICES`, `FINALIZED_ACCOUNTING_INVOICES`, `PAYMENTS_HELD`, `DEPOSITS_HELD`, `SALES_QUOTES`, `SEASON_CALENDAR_DAYS`.
* `VEHICLE_UNAVAILABLE`, `reasons[]` : `BOOKED`, `BLOCKED`, `BUFFER`, `INACTIVE`, `ARCHIVED`, `BREAKDOWN`, `MAINTENANCE_OVERDUE`, `NO_PRICING_CATEGORY`.
* `VEHICLE_UNAVAILABLE`, `conflicts[].kind` : `RENTAL`, `VEHICLE_BLOCK`.
* `BOOKING_RULE_VIOLATION`, `rule` : `LEAD_TIME`, `HORIZON`, `MIN_DURATION`, `CLOSED_DAY`, `OUTSIDE_HOURS`.
* `PAYMENT_NOT_VERIFIED`, `reason` : `PI_NOT_FOUND`, `PI_NOT_SUCCEEDED`, `PI_ALREADY_USED`, `PI_RENTAL_MISMATCH`, `CURRENCY_MISMATCH`, `AMOUNT_MISMATCH`, `CONNECT_NOT_CONFIGURED`.
* `PRICING_CHOICE_NOT_AVAILABLE`, `availablePricingChoices[].pricingChoice` : `KEEP_ORIGINAL_PRICE`, `APPLY_LOWER_PRICE`, `APPLY_NEW_PRICE`, `APPLY_PRORATA`.
* `PROMO_CODE_REJECTED`, `reason` : `NOT_FOUND`, `NOT_STARTED`, `EXPIRED`, `EXHAUSTED`, `BELOW_MIN_DURATION`, `CATEGORY_NOT_ELIGIBLE`, `NO_DISCOUNT`.
* `VAT_REVERSE_CHARGE_NOT_ALLOWED`, `reason` : `NOT_ENABLED`, `ORGANIZATION_VAT_NUMBER_MISSING`, `CUSTOMER_VAT_NUMBER_MISSING`.
* `RATE_LIMITED`, `limit` : `PRE_AUTH`, `PER_KEY`, `WRITE`, `QUOTE`.
* `SERVICE_UNAVAILABLE`, `dependency` : `PAYMENT_PROVIDER`, `FILE_STORAGE`, `ACCOUNTING`, `EMAIL`.

Le sens des valeurs de `PAYMENT_NOT_VERIFIED.reason` est détaillé dans [Intégration d’une plateforme de réservation](https://docs.lexio.rent/integration-broker.md) ; `action` et `allowedStatuses` de `RENTAL_STATUS_NOT_ALLOWED` dans [Cycle de vie d’une location](https://docs.lexio.rent/cycle-de-vie.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.