> ## 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.

# Authentification et scopes

## La clé API

L’API s’authentifie par clé API seule, sans connexion d’utilisateur. La clé commence par `lck_` et s’envoie en en-tête, jamais dans l’adresse :

```
Authorization: Bearer lck_xxxxxxxxxxxxx
```

Appelez l’API depuis un serveur : elle n’émet aucun en-tête CORS, et une clé ne doit figurer ni dans une page web ni dans une application installée. Une clé envoyée hors de `/api/external/v1` répond `403` dans un autre format d’erreur : vérifiez l’adresse de base.

## Deux types de clés

Une clé appartient à une seule organisation (un loueur). Elle est **partenaire** si elle porte un code partenaire (`partnerCode`), **interne** sinon.

| | Clé interne | Clé partenaire |
| - | - | - |
| Usage | outils du loueur (site, logiciel, automatisations) | plateforme tierce qui vend les véhicules du loueur |
| Périmètre | toute l’organisation | ses locations, devis, clients et événements ; le reste répond `404` |
| Scopes | tous | ceux marqués « oui » dans la table des scopes |
| Règles de réservation du loueur (horaires, préavis, horizon, durée minimale) | non appliquées | appliquées : `422 BOOKING_RULE_VIOLATION` |
| Titulaire d’une location | `customerId` ou `customer` | `customer` seul |
| Paiements | tous les moyens ; remboursements avec `payments.refund` | encaissement Stripe (`PAYMENT`) seulement |
| Frais libres (`charges`), conducteur additionnel, autoliquidation (`isVatReverseCharge`) ; notes internes à la création | oui | non (`400 not_applicable`) |
| Email de confirmation au client | selon le réglage du loueur | jamais |

Parcours complet d’une clé partenaire : [Intégration d’une plateforme de réservation](https://docs.lexio.rent/integration-broker.md).

## Obtenir une clé

Le loueur crée la clé dans Lexio ; vous ne pouvez pas la créer vous-même. Premier accès ou organisation de test : [contact@lexio.rent](mailto:contact@lexio.rent).

1. Le plan du loueur doit inclure l’API (table des fonctionnalités ci-dessous), sinon chaque appel répond `403 FEATURE_NOT_AVAILABLE`.
2. Le propriétaire de l’organisation, ou un membre autorisé à gérer les clés API, ouvre Paramètres → Développeur.
3. Il choisit les scopes, parmi les droits qu’il détient lui-même, et, pour un partenaire, le code partenaire : 2 à 50 caractères parmi `a-z`, `0-9`, `-` et `_`, commençant par une lettre ou un chiffre. Ni l’un ni l’autre ne se modifie ensuite.
4. Il choisit l’expiration : 30, 90, 180 ou 365 jours (par défaut), ou jamais.
5. La clé complète ne s’affiche qu’une fois : il la copie et vous la transmet par un canal sûr.

Une organisation a au plus 20 clés non révoquées (désactivées et expirées comprises). Pour vérifier une clé, `GET /organization` renvoie son nom, son code partenaire, ses scopes et son expiration (`apiKey.expiresAt`).

## États de la clé

| Situation | Statut | `code` | Qui agit |
| - | - | - | - |
| Clé absente de la requête | 401 | `API_KEY_MISSING` | vous |
| En-tête mal formé ou clé inconnue | 401 | `API_KEY_INVALID` | vous |
| Clé désactivée | 401 | `API_KEY_DISABLED` | le loueur la réactive, la même clé refonctionne |
| Clé révoquée | 401 | `API_KEY_REVOKED` | le loueur en crée une nouvelle |
| Clé expirée | 401 | `API_KEY_EXPIRED` | le loueur en crée une nouvelle |
| Scope manquant | 403 | `INSUFFICIENT_SCOPE` | le loueur crée une clé qui porte le scope |
| Organisation suspendue | 403 | `ORGANIZATION_SUSPENDED` | le loueur régularise son abonnement |
| Plan sans la fonctionnalité de l’opération | 403 | `FEATURE_NOT_AVAILABLE` | le loueur change de plan |

Toute réponse `401` porte `WWW-Authenticate: Bearer realm="Lexio API"`, plus `error="invalid_token"` si un en-tête `Authorization` a été envoyé.

## Rotation

Pour remplacer une clé sans coupure, le loueur crée une seconde clé (mêmes scopes, même code partenaire) ; vous basculez vos appels et attendez 24 h (une `Idempotency-Key` ne vaut que pour la clé qui l’a envoyée) ; il révoque l’ancienne. Vos locations, devis, clients et événements sont liés au code partenaire, pas à la clé.

La clé appartient à l’organisation, pas à son créateur : elle fonctionne encore s’il quitte l’équipe. Ses écritures sont signées « API : nom de la clé » (suivi du code partenaire s’il existe) dans les notes, les paiements et le journal d’activité du loueur.

## Requêtes

* Corps JSON UTF-8 de 1 Mio au plus, en `application/json` (`application/merge-patch+json` aussi sur `PATCH`). Trop gros : `413` ; autre type : `415` ; JSON illisible : `400`.
* Un champ inconnu dans une requête est refusé (`400`) ; dans une réponse, ignorez-le ([Versions et évolutions](https://docs.lexio.rent/versions.md)).
* Chaque réponse porte `X-Request-Id`, repris dans `requestId` des erreurs. Vous pouvez fournir le vôtre (8 à 128 caractères parmi `A-Za-z0-9._:-`), sinon le serveur en génère un. Joignez-le à toute demande à [contact@lexio.rent](mailto:contact@lexio.rent).

## Scopes

Un scope s’écrit `<ressource>.<accès>` : `read` couvre les lectures de la ressource et de ses sous-ressources, `write` les créations, modifications et actions ; les droits sensibles ont leur propre scope. Une opération accepte l’un des scopes listés. `GET /organization` s’ouvre à toute clé valide ; `offers.read` et `quotes.write` suffisent pour chiffrer sans accéder aux locations.

| Scope | Libellé | Clé partenaire | Opérations |
| - | - | - | - |
| (aucun) | Toute clé valide | oui | `GET /organization` |
| `offers.read` | Consulter les disponibilités et les devis | oui | `GET /availability`, `GET /quotes/{quoteId}` |
| `quotes.write` | Créer des devis | oui | `POST /quotes` |
| `rentals.read` | Voir les locations | oui | `GET /events`, `GET /rentals`, `GET /rentals/{rentalId}`, `GET /rentals/{rentalId}/amendments`, `GET /rentals/{rentalId}/contract`, `GET /rentals/{rentalId}/inspections`, `GET /rentals/{rentalId}/invoices`, `GET /rentals/{rentalId}/payments`, `GET /rentals/{rentalId}/payments/{paymentId}`, `GET /rentals/{rentalId}/photos`, `GET /rentals/{rentalId}/photos/{photoId}` |
| `rentals.write` | Créer et modifier les locations | oui | `POST /rentals`, `PATCH /rentals/{rentalId}`, `POST /rentals/{rentalId}/cancel`, `POST /rentals/{rentalId}/change-coverage`, `POST /rentals/{rentalId}/change-customer`, `POST /rentals/{rentalId}/change-vehicle`, `DELETE /rentals/{rentalId}/options/{optionId}`, `PUT /rentals/{rentalId}/options/{optionId}`, `POST /rentals/{rentalId}/reschedule` |
| `rentals.operate` | Départs, retours et photos | non | `POST /rentals/{rentalId}/photo-uploads`, `POST /rentals/{rentalId}/photos`, `DELETE /rentals/{rentalId}/photos/{photoId}`, `POST /rentals/{rentalId}/pickup`, `POST /rentals/{rentalId}/return` |
| `rentals.delete` | Supprimer les locations | non | `DELETE /rentals/{rentalId}` |
| `payments.write` | Enregistrer des paiements | oui | `POST /rentals/{rentalId}/payments` |
| `payments.refund` | Rembourser | non | `POST /rentals/{rentalId}/payments`, `DELETE /rentals/{rentalId}/payments/{paymentId}` |
| `customers.read` | Voir les clients | non | `GET /customers`, `GET /customers/{customerId}` |
| `customers.write` | Créer et modifier les clients | non | `POST /customers`, `PATCH /customers/{customerId}` |
| `customers.delete` | Supprimer les clients | non | `DELETE /customers/{customerId}` |
| `vehicles.read` | Voir les véhicules et leurs blocages | non | `GET /vehicle-blocks`, `GET /vehicles`, `GET /vehicles/{vehicleId}` |
| `vehicles.write` | Créer, modifier et archiver les véhicules | non | `POST /vehicles`, `PATCH /vehicles/{vehicleId}`, `POST /vehicles/{vehicleId}/archive`, `POST /vehicles/{vehicleId}/unarchive` |
| `vehicles.delete` | Supprimer les véhicules | non | `DELETE /vehicles/{vehicleId}` |
| `catalog.read` | Voir le catalogue (catégories, options, franchises, cautions, forfaits) | oui | `GET /categories`, `GET /categories/{categoryId}`, `GET /deductibles`, `GET /deductibles/{deductibleId}`, `GET /deposits`, `GET /deposits/{depositId}`, `GET /locations`, `GET /mileage-packages`, `GET /mileage-packages/{mileagePackageId}`, `GET /options`, `GET /options/{optionId}` |
| `catalog.write` | Modifier le catalogue | non | `POST /categories`, `DELETE /categories/{categoryId}`, `PATCH /categories/{categoryId}`, `POST /deductibles`, `DELETE /deductibles/{deductibleId}`, `PATCH /deductibles/{deductibleId}`, `POST /deposits`, `DELETE /deposits/{depositId}`, `PATCH /deposits/{depositId}`, `POST /mileage-packages`, `DELETE /mileage-packages/{mileagePackageId}`, `PATCH /mileage-packages/{mileagePackageId}`, `POST /options`, `DELETE /options/{optionId}`, `PATCH /options/{optionId}` |
| `pricing.read` | Voir la tarification (saisons, remises, délais) | non | `GET /duration-discounts`, `GET /duration-discounts/{durationDiscountId}`, `GET /lead-time-tiers`, `GET /lead-time-tiers/{leadTimeTierId}`, `GET /pricing-settings`, `GET /season-calendar`, `GET /season-calendar/{month}`, `GET /seasons`, `GET /seasons/{slug}` |
| `pricing.write` | Modifier la tarification | non | `POST /duration-discounts`, `DELETE /duration-discounts/{durationDiscountId}`, `PATCH /duration-discounts/{durationDiscountId}`, `PATCH /lead-time-tiers/{leadTimeTierId}`, `PUT /season-calendar/{month}`, `PATCH /seasons/{slug}` |
| `maintenance.read` | Voir les entretiens | non | `GET /maintenance-operations`, `GET /maintenance-records`, `GET /maintenance-records/{maintenanceRecordId}`, `GET /vehicles/{vehicleId}/maintenance-alerts` |
| `maintenance.write` | Gérer les entretiens | non | `POST /maintenance-records`, `DELETE /maintenance-records/{maintenanceRecordId}`, `PATCH /maintenance-records/{maintenanceRecordId}` |

## Fonctionnalités du plan

Sans la fonctionnalité requise par le plan du loueur, une opération répond `403 FEATURE_NOT_AVAILABLE`, et `feature` la nomme. La table donne les plans standard ; Lexio peut aussi ouvrir une fonctionnalité à une organisation précise.

| Fonctionnalité (`feature`) | Libellé | Plans qui l’incluent | Opérations |
| - | - | - | - |
| `api.external` | API externe | Business | toutes |
| `maintenance.manage` | Suivi maintenance & alertes | Pro, Business | `POST /maintenance-records`, `DELETE /maintenance-records/{maintenanceRecordId}`, `PATCH /maintenance-records/{maintenanceRecordId}` |
| `mileage.basic` | Km inclus + facturation dépassement | Starter, Pro, Business | `GET /mileage-packages`, `POST /mileage-packages`, `DELETE /mileage-packages/{mileagePackageId}`, `GET /mileage-packages/{mileagePackageId}`, `PATCH /mileage-packages/{mileagePackageId}` |
| `pricing.deposits` | Dépôts & franchises | Starter, Pro, Business | `GET /deposits`, `POST /deposits`, `DELETE /deposits/{depositId}`, `GET /deposits/{depositId}`, `PATCH /deposits/{depositId}` |
| `pricing.discounts` | Remises par durée | Pro, Business | `GET /duration-discounts`, `POST /duration-discounts`, `DELETE /duration-discounts/{durationDiscountId}`, `GET /duration-discounts/{durationDiscountId}`, `PATCH /duration-discounts/{durationDiscountId}` |
| `pricing.leadtime` | Tarification Lead Time | Business | `GET /lead-time-tiers`, `GET /lead-time-tiers/{leadTimeTierId}`, `PATCH /lead-time-tiers/{leadTimeTierId}` |
| `pricing.options` | Options de location | Pro, Business | `GET /options`, `POST /options`, `DELETE /options/{optionId}`, `GET /options/{optionId}`, `PATCH /options/{optionId}`, `DELETE /rentals/{rentalId}/options/{optionId}`, `PUT /rentals/{rentalId}/options/{optionId}` |
| `pricing.seasons` | Tarification dynamique | Pro, Business | `GET /season-calendar`, `GET /season-calendar/{month}`, `PUT /season-calendar/{month}`, `GET /seasons`, `GET /seasons/{slug}`, `PATCH /seasons/{slug}` |

En plus : des `options` dans un devis ou une location exigent `pricing.options` (une location sans devis exige un plan qui l’inclut ; une ouverture propre à l’organisation ne suffit qu’en passant par un devis) ; démarrer le suivi d’entretien d’un véhicule (`maintenanceTrackingMode`) exige `maintenance.manage` et le scope `maintenance.write`.


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