Démarrage rapide

De la recherche d'un véhicule à l'annulation, en cinq appels. Vous avez besoin d'une clé API (voir « Authentification et scopes »), d'une organisation au plan Business, d'un véhicule actif rattaché à une catégorie tarifaire avec prix, et des scopes offers.read, quotes.write, rentals.read et rentals.write.

Les dates sont calculées dans le shell (dans 30 jours, pour 5 jours) : elles restent futures. Remplacez <vehicle-uuid> par le data[].vehicle.id lu à l'étape 1, <quote-uuid> par le data.id lu à l'étape 2 et <rental-uuid> par le data.id lu à l'étape 3.

# 0. Clé API (Paramètres → Développeur) et adresse de base.
export LEXIO_KEY="lck_xxxxxxxxxxxxxxxxxxxxxxxx"
export LEXIO_API="https://api.lexio.rent/api/external/v1"
# Un numéro de commande unique par essai : une partnerReference déjà utilisée répond 409 ALREADY_EXISTS.
export REF="quickstart-$(date +%s)"
# Dates futures, date GNU puis BSD/macOS.
export START=$(date -d '+30 days' +%F 2>/dev/null || date -v+30d +%F)
export END=$(date -d '+35 days' +%F 2>/dev/null || date -v+35d +%F)

# 1. Véhicules réservables et prix (offers.read) ; lisez data[].vehicle.id
curl "$LEXIO_API/availability?startAt=${START}T10:00&endAt=${END}T10:00&isAvailable=true" \
  -H "Authorization: Bearer $LEXIO_KEY"

# 2. Devis au prix garanti 24 h (quotes.write) ; lisez data.id et data.totalTTC
curl -X POST "$LEXIO_API/quotes" \
  -H "Authorization: Bearer $LEXIO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicleId": "<vehicle-uuid>",
    "startAt": "'"$START"'T10:00",
    "endAt": "'"$END"'T10:00"
  }'

# 3. Créer la location au prix du devis (rentals.write) ; lisez data.id
curl -X POST "$LEXIO_API/rentals" \
  -H "Authorization: Bearer $LEXIO_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "<quote-uuid>",
    "partnerReference": "'"$REF"'",
    "customer": {
      "firstName": "Marie",
      "lastName": "Durand",
      "email": "marie@example.com",
      "phone": "+33612345678"
    }
  }'

# 4. Relire la location (rentals.read) ; lisez data.totalTTC et data.balance
curl "$LEXIO_API/rentals/<rental-uuid>" -H "Authorization: Bearer $LEXIO_KEY"

# 5. Annuler avec un motif (rentals.write) ; lisez effects.cancellation
curl -X POST "$LEXIO_API/rentals/<rental-uuid>/cancel" \
  -H "Authorization: Bearer $LEXIO_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Annulation du démarrage rapide" }'

Ce qu'il faut retenir :

Authentification et scopes

La clé API

L'API s'authentifie par clé API uniquement, sans connexion d'utilisateur. La clé commence par lck_ ; le loueur la crée dans Lexio (Paramètres → Développeur) et vous la transmet. Seul le propriétaire de l'organisation, ou un membre autorisé par le propriétaire à gérer les clés API, peut la créer.

La clé s'envoie dans un seul en-tête, jamais dans l'adresse :

Authorization: Bearer lck_xxxxxxxxxxxxx

L'API se consomme depuis votre serveur : elle n'émet aucun en-tête CORS et une clé ne doit jamais être embarquée dans une page web ni dans une application installée. Une clé envoyée à une autre adresse que l'API externe est refusée (403) : vérifiez que vous appelez bien la base de l'API externe indiquée dans la référence.

Appartenance et auteur des écritures

La clé appartient à l'organisation, pas à la personne qui l'a créée : elle continue de fonctionner si ce membre perd des droits ou quitte l'équipe. Les écritures faites avec la clé sont signées « API : nom de la clé » (suivi de l'identifiant partenaire entre parenthèses s'il existe) dans les notes, les paiements et le journal d'activité du loueur.

États de la clé

SituationStatutcodeQui agit
Clé absente de la requête401API_KEY_MISSINGvous
En-tête mal formé ou clé inconnue401API_KEY_INVALIDvous
Clé désactivée401API_KEY_DISABLEDle loueur la réactive, la même clé refonctionne
Clé révoquée401API_KEY_REVOKEDle loueur en crée une nouvelle
Clé expirée401API_KEY_EXPIREDle loueur en crée une nouvelle
Scope manquant403INSUFFICIENT_SCOPEle loueur crée une clé qui porte le scope
Organisation suspendue403ORGANIZATION_SUSPENDEDle loueur régularise son abonnement
Abonnement sans la fonctionnalité de la route403FEATURE_NOT_AVAILABLEle loueur change d'abonnement

Toute réponse 401 porte WWW-Authenticate: Bearer realm="Lexio API", complété de error="invalid_token" dès qu'un en-tête Authorization a été envoyé.

Expiration et rotation

Une clé expire par défaut au bout de 365 jours. Pour la remplacer sans coupure : créez une seconde clé avec les mêmes scopes (et le même identifiant partenaire), basculez vos appels, attendez 24 h (durée de vie des Idempotency-Key, propres à chaque clé : un rejeu ne passe pas d'une clé à l'autre), puis faites révoquer l'ancienne.

Corrélation des requêtes

Chaque réponse porte X-Request-Id, repris dans le champ requestId des erreurs : communiquez-le au support. Vous pouvez fournir le vôtre dans X-Request-Id (8 à 128 caractères parmi A-Za-z0-9._:-) ; sinon le serveur en génère un.

Corps de requête

JSON UTF-8 de 1 Mio au plus, en application/json (application/merge-patch+json aussi sur PATCH). Au-delà, 413 ; autre type de contenu, 415 ; JSON illisible, 400. Les champs inconnus sont refusés (400).

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 scope propre. Une opération accepte l'un des scopes listés (OU logique). GET /organization s'ouvre à toute clé valide. Un scope se choisit à la création de la clé et ne se modifie pas.

ScopeLibelléOpérations
(aucun)Toute clé valideGET /organization
offers.readConsulter les disponibilités et les devisGET /availability, GET /quotes/{quoteId}
quotes.writeCréer des devisPOST /quotes
rentals.readVoir les locationsGET /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.writeCréer et modifier les locationsPOST /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.operateDéparts, retours et photosPOST /rentals/{rentalId}/photo-uploads, POST /rentals/{rentalId}/photos, DELETE /rentals/{rentalId}/photos/{photoId}, POST /rentals/{rentalId}/pickup, POST /rentals/{rentalId}/return
rentals.deleteSupprimer les locationsDELETE /rentals/{rentalId}
payments.writeEnregistrer des paiementsPOST /rentals/{rentalId}/payments
payments.refundRembourserPOST /rentals/{rentalId}/payments, DELETE /rentals/{rentalId}/payments/{paymentId}
customers.readVoir les clientsGET /customers, GET /customers/{customerId}
customers.writeCréer et modifier les clientsPOST /customers, PATCH /customers/{customerId}
customers.deleteSupprimer les clientsDELETE /customers/{customerId}
vehicles.readVoir les véhicules et leurs blocagesGET /vehicle-blocks, GET /vehicles, GET /vehicles/{vehicleId}
vehicles.writeCréer et modifier les véhicules et leurs blocagesPOST /vehicles, PATCH /vehicles/{vehicleId}, POST /vehicles/{vehicleId}/archive, POST /vehicles/{vehicleId}/unarchive
vehicles.deleteSupprimer les véhiculesDELETE /vehicles/{vehicleId}
catalog.readVoir le catalogue (catégories, options, franchises, cautions, forfaits)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.writeModifier le cataloguePOST /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.readVoir la tarification (saisons, remises, délais)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.writeModifier la tarificationPOST /duration-discounts, DELETE /duration-discounts/{durationDiscountId}, PATCH /duration-discounts/{durationDiscountId}, PATCH /lead-time-tiers/{leadTimeTierId}, PUT /season-calendar/{month}, PATCH /seasons/{slug}
maintenance.readVoir les entretiensGET /maintenance-operations, GET /maintenance-records, GET /maintenance-records/{maintenanceRecordId}, GET /vehicles/{vehicleId}/maintenance-alerts
maintenance.writeGérer les entretiensPOST /maintenance-records, DELETE /maintenance-records/{maintenanceRecordId}, PATCH /maintenance-records/{maintenanceRecordId}

offers.read et quotes.write permettent de chiffrer sans ouvrir le registre des locations.

Limites de débit

Quatre seaux protègent l'API. Une requête refusée répond 429 RATE_LIMITED, avec Retry-After (secondes) ; le corps indique le seau (limit), sa fenêtre (windowSeconds) et le délai (retryAfter).

Seau (limit)PlafondCompté parS’applique à
PRE_AUTH30 requêtes / 1 minadresse IPles échecs d’authentification qu’aucune clé ne peut se voir attribuer (clé absente ou inconnue)
PER_KEY120 requêtes / 1 minclé APItoute requête d’une clé authentifiée, erreurs comprises
WRITE30 requêtes / 5 minclé APIPOST /rentals, POST /rentals/{rentalId}/photo-uploads, POST /rentals/{rentalId}/photos
WRITE60 requêtes / 1 minclé APItoute autre écriture (POST, PUT, PATCH, DELETE)
QUOTE120 requêtes / 1 minclé APIPOST /quotes et toute requête avec ?dryRun=true

Pagination

Toute liste utilise un curseur, partout :

{ "data": [ … ], "nextCursor": "eyJ…" }

Filtres

Idempotence et reprise

Idempotency-Key

Une écriture réseau peut échouer après avoir réussi. Envoyez une Idempotency-Key pour la rejouer sans risque de doublon.

Quels codes rejouer

RéponseQue faire
Erreur réseau, délai dépassé, 500, 503rejouer à l'identique avec la même Idempotency-Key (après Retry-After s'il existe) ; sur une écriture qui ne déclare pas IDEMPOTENCY_ALREADY_APPLIED, relire d'abord la ressource
409 IDEMPOTENCY_IN_FLIGHT, 409 RENTAL_BUSYattendre Retry-After, puis rejouer à l'identique
409 IDEMPOTENCY_ALREADY_APPLIEDne pas rejouer : relire la ressource désignée
429attendre Retry-After, puis rejouer à l'identique
409 RENTAL_CHANGED, PRICE_CHANGEDrelire la ressource, puis décider : ne rejouez pas à l'aveugle
Autres 4xxcorriger la requête ; une nouvelle tentative utilise une nouvelle clé

Votre numéro de commande

partnerReference est votre numéro de commande : unique par identifiant partenaire, il n'est pas un mécanisme de rejeu. Un doublon répond 409 ALREADY_EXISTS (field, conflictingId). Ne l'alimentez jamais avec un identifiant de paiement : une réservation a sa propre identité, indépendante du cycle de vie du paiement. Le rejeu sûr passe par Idempotency-Key.

Action déjà faite

Une action sur une location déjà dans l'état visé répond 409 RENTAL_STATUS_NOT_ALLOWED. L'annulation d'une location déjà annulée fait exception : elle répond 200 sans rien écrire, avec effects.cancellation.alreadyCancelled: true.

Aperçu avant écriture

?dryRun=true exécute l'action jusqu'au bout, puis l'annule : la réponse est identique à l'appel réel, y compris effects.priceChange et effects.overpayment, et rien n'est enregistré.

Synchronisation par événements

GET /events est le flux ordonné des changements de locations. Il remplace l'interrogation périodique des listes et ne demande aucun webhook.

GET /api/external/v1/events?cursor=…&limit=100&types=rental.created,rental.cancelled
{
  "data": [
    {
      "id": "4e1a…",
      "type": "rental.cancelled",
      "occurredAt": "2027-06-01T09:12:44+02:00",
      "resource": { "type": "RENTAL", "id": "9c2d…", "partnerReference": "LR-884213" }
    }
  ],
  "nextCursor": "…"
}

Boucle de synchronisation

  1. Première lecture : sans paramètre (ou start=EARLIEST), le flux repart des événements des 29 derniers jours ; start=LATEST ne renvoie aucun événement mais le curseur d'aujourd'hui, pour ne suivre que ce qui suit. start et cursor s'excluent.
  2. Traitez les événements d'une page, puis enregistrez son nextCursor. Le curseur est toujours renvoyé, même sur une page vide : rejouez-le tel quel.
  3. Reprenez au curseur enregistré, à la cadence qui vous convient, en respectant les limites de débit.

Reprise après une longue absence

Les événements sont conservés 30 jours. Un curseur plus ancien répond 410 CURSOR_EXPIRED : resynchronisez en lisant d'abord GET /events?start=LATEST (enregistrez son curseur), puis parcourez GET /rentals page par page pour reconstruire l'état, et reprenez le flux au curseur enregistré. Rien de ce qui a changé pendant le parcours n'est perdu.

Versions et évolutions

La version majeure est dans l'adresse : /api/external/v1. La documentation décrit le contrat en vigueur ; son numéro (info.version) suit le versionnage sémantique, par exemple 1.0.0. La date de chaque changement figure dans le changelog publié de l'API.

Évolutions sans préavis

Elles ne cassent aucun client qui respecte ces règles : ignorez les champs de réponse que vous ne connaissez pas.

Nouvelle valeur d'une énumération en sortie

Elle est annoncée 30 jours avant. Tolérez une valeur inconnue : ne basez pas un switch sans branche par défaut sur une énumération de sortie.

Correctifs de contrat

Un correctif de sécurité, d'intégrité des données ou de bug, ou l'alignement de la référence sur le comportement réel, s'applique à la v1 sans préavis. Il est daté dans le changelog, avec la marche à suivre.

Évolutions cassantes

Hors correctif de contrat, elles ne paraissent que dans une nouvelle version majeure (v2), servie en parallèle. La v1 reste disponible 6 mois après l'annonce, et ses réponses portent les en-têtes Deprecation et Sunset.

Erreurs

Toute réponse 4xx ou 5xx est un objet RFC 9457 (application/problem+json). Le code est la référence stable, lisible par une machine ; title et detail sont rédigés en français et peuvent évoluer : ne les analysez pas.

{
  "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/9c2d…/cancel",
  "requestId": "9b2d6c1e-4f3a-4e8b-a1d7-3c5e9f0a2b46"
}

Que faire selon le statut

StatutSignificationVotre réaction
400la forme de la requête est invalide (JSON, type, format, champ inconnu ou manquant)corriger la requête
401clé absente, invalide, désactivée, révoquée ou expiréechanger de clé
403scope manquant, organisation suspendue, fonctionnalité hors abonnementdemander l'accès au loueur
404cible inexistante ou hors du périmètre de la cléne pas réessayer
405, 410, 413, 415méthode, curseur expiré, taille, type de contenucorriger
409l'état d'une ressource (location, véhicule, client, devis) ou une écriture concurrente empêche l'opération : la même requête peut réussir plus tard sans modificationrelire l'état ; ne réessayer que si le code est rejouable
422requête bien formée mais refusée par une règle de configuration ou de données (référence, règle de réservation, plafond, montant)changer les données
429débitattendre Retry-After
500, 503incident ou dépendance indisponiblerejouer avec la même Idempotency-Key, après Retry-After si présent (un 500 n'en porte pas : patienter quelques secondes) ; voir « Idempotence et reprise » avant de rejouer une écriture

Un même refus a le même statut et le même code sur toutes les routes.

Catalogue des codes

CodeStatutTitreChamps supplémentairesRetry-After
MALFORMED_REQUEST400Corps de requête illisible——
VALIDATION_FAILED400Requête invalideerrors[]—
API_KEY_DISABLED401Clé API désactivée——
API_KEY_EXPIRED401Clé API expirée——
API_KEY_INVALID401Clé API invalide——
API_KEY_MISSING401Clé API absente——
API_KEY_REVOKED401Clé API révoquée——
FEATURE_NOT_AVAILABLE403Fonctionnalité non inclusefeature—
INSUFFICIENT_SCOPE403Scope insuffisantrequiredScopes—
ORGANIZATION_SUSPENDED403Organisation suspendue——
NOT_FOUND404Ressource introuvableresource—
ROUTE_NOT_FOUND404Route inconnue——
METHOD_NOT_ALLOWED405Méthode non autoriséeallowed—
ALREADY_EXISTS409Doublonfield, conflictingId—
BOOKING_REFUSED409Réservation refusée——
CREDIT_NOTE_NOT_ISSUABLE409Avoir impossible à émettre——
CUSTOMER_ANONYMIZED409Client anonymisé——
CUSTOMER_BLOCKED409Client bloqué——
DEFAULT_ITEM_REQUIRED409Élément par défaut requis——
IDEMPOTENCY_ALREADY_APPLIED409Écriture déjà appliquéeresourceId—
IDEMPOTENCY_IN_FLIGHT409Requête identique en cours—oui
INVOICE_FINALIZED409Facture finalisée——
MAINTENANCE_TRACKING_ALREADY_STARTED409Suivi d'entretien déjà démarrémaintenanceTrackingMode—
MAINTENANCE_TRACKING_NOT_STARTED409Suivi d'entretien non démarré——
OPTION_UNAVAILABLE409Option en ruptureoptionId, availableQuantity—
OVERPAYMENT_RESOLUTION_REQUIRED409Trop-perçu à résoudreoverpaidAmount, resolvableByKey—
PAYMENT_PROVIDER_MANAGED409Paiement géré par le prestataire——
PRICE_CHANGED409Prix modifiéexpectedTotalTTC, currentTotalTTC—
QUOTE_ALREADY_USED409Devis déjà utilisérentalId—
QUOTE_EXPIRED409Devis expiré——
RANGE_OVERLAP409Plages qui se chevauchenterrors[], conflictingId, minRentalDays, maxRentalDays, minLeadDays, maxLeadDays—
RENTAL_BUSY409Location occupée—oui
RENTAL_CHANGED409Location modifiée entre-temps——
RENTAL_STATUS_NOT_ALLOWED409Statut de la location incompatibleerrors[], rentalStatus, allowedStatuses, action—
RESOURCE_IN_USE409Ressource utiliséeblockers—
SEPA_DEBIT_PENDING409Prélèvement SEPA en courspendingDebitAmount—
VEHICLE_ARCHIVED409Véhicule archivé——
VEHICLE_UNAVAILABLE409Véhicule indisponiblereasons, conflicts, overdueOperations—
CURSOR_EXPIRED410Curseur expiré——
PAYLOAD_TOO_LARGE413Corps trop volumineuxmaxBytes—
UNSUPPORTED_MEDIA_TYPE415Type de contenu non pris en chargeaccepted—
BOOKING_RULE_VIOLATION422Règle de réservation non respectéeerrors[], rule—
DISCOUNT_CAP_EXCEEDED422Plafond de remise dépasséerrors[], maxDiscountPercent—
DRIVER_AGE_MISMATCH422Âge du conducteur différent du deviserrors[]—
IDEMPOTENCY_KEY_REUSED422Clé d'idempotence réutilisée——
LIMIT_EXCEEDED422Limite atteinteresource, max—
OPTION_OUT_OF_SEASON422Option hors saisonerrors[]—
OPTION_QUANTITY_EXCEEDED422Quantité d'option dépasséeerrors[], maxQuantity—
PAYMENT_EXCEEDS_DUE422Encaissement supérieur au dûerrors[], dueAmount—
PAYMENT_NOT_VERIFIED422Paiement non vérifiéerrors[], reason—
PRICING_CHOICE_NOT_AVAILABLE422Choix tarifaire indisponibleerrors[], availablePricingChoices—
PROMO_CODE_REJECTED422Code promo refuséerrors[], reason, minRentalDays—
REFERENCE_INACTIVE422Référence inactiveerrors[]—
REFERENCE_NOT_FOUND422Référence introuvableerrors[]—
REFUND_EXCEEDS_PAID422Remboursement supérieur à l'encaisséerrors[], maxRefundableAmount—
UPLOAD_INVALID422Téléversement invalideerrors[]—
VAT_REVERSE_CHARGE_NOT_ALLOWED422Autoliquidation impossiblereason—
RATE_LIMITED429Trop de requêteslimit, windowSeconds, retryAfteroui
INTERNAL_ERROR500Erreur interne——
SERVICE_UNAVAILABLE503Service momentanément indisponibledependencyoui

Intégration broker

Parcours d'une plateforme de réservation qui vend des véhicules de plusieurs loueurs Lexio.

Une clé par loueur

Une clé appartient à une seule organisation : il n'existe pas de clé multi-organisation. Chaque loueur crée la sienne (Paramètres → Développeur) et vous la transmet. Contrôlez-la avec GET /organization : devise, fuseau, TVA, horaires d'ouverture, règles de réservation et scopes de la clé.

Identifiant partenaire

Une clé peut porter un identifiant partenaire (partnerCode), fixé à sa création et non modifiable. Il cloisonne votre espace :

Scopes accordables à une clé partenaire : catalog.read, offers.read, quotes.write, rentals.read, rentals.write et payments.write (limité aux paiements Stripe). Les autres sont refusés à la création de la clé.

Parcours de réservation

  1. GET /availability : véhicules réservables et prix pour la période, selon les règles de réservation du loueur (422 BOOKING_RULE_VIOLATION). Prix et disponibilité ne sont pas garantis.
  2. POST /quotes : prix garanti 24 h (expiresAt), consommable une seule fois. Le devis ne réserve rien.
  3. POST /rentals avec quoteId, votre numéro de commande en partnerReference et une Idempotency-Key. La disponibilité est revérifiée (409 VEHICLE_UNAVAILABLE) ; si le prix recalculé s'écarte du devis, 409 PRICE_CHANGED et rien n'est créé.
  4. Lisez le total TTC dans totalTTC et le reste à payer dans balance de la location.

Votre numéro de commande est la référence de la réservation : n'y mettez pas un identifiant de paiement. Pour retrouver une location : GET /rentals?partnerReference=… ou GET /rentals?number=… (numéro Lexio).

Paiement

Enregistrez un paiement par POST /rentals/{rentalId}/payments. Une clé partenaire n'enregistre que des paiements Stripe, par leur identifiant de paiement ; les remboursements sont réservés au loueur. Si une modification fait passer le total sous le montant encaissé, la réponse est 409 OVERPAYMENT_RESOLUTION_REQUIRED avec resolvableByKey: false : le loueur traite la baisse dans Lexio.

Suivi, modification, annulation

Effets sur le client final

Une clé partenaire n'envoie jamais d'email de confirmation au client final. Le loueur est alerté de chaque création.

Pas de bac à sable

Testez sur une organisation de test du loueur, avec des dates futures, puis annulez.

Rotation de clé

Voir « Authentification et scopes » : deux clés actives avec le même identifiant partenaire pendant la bascule. Vos références, devis, clients et événements sont liés à l'identifiant partenaire, pas à la clé.

Ce qui se gère dans Lexio

Principe : tout ce qui bloque une action de l'API est lisible par l'API (la cause figure dans l'erreur et la ressource est consultable), et modifiable par l'API, sauf les exceptions ci-dessous. Elles se gèrent dans l'application Lexio, par le loueur.

SujetCe qui bloqueLecture par l'APIPourquoi dans Lexio
Blocages de planningVEHICLE_UNAVAILABLE (raison BLOCKED)GET /vehicle-blocksoutil de planning du loueur ; les blocages d'entretien se créent et se suppriment avec /maintenance-records
Contrôle techniqueVEHICLE_UNAVAILABLE (raison MAINTENANCE_OVERDUE)GET /vehicles/{vehicleId}/maintenance-alertssuivi réglementaire : absent de /maintenance-records (404), non saisissable ; l'échéance reste visible dans les alertes
Réinitialisation du suivi d'entretienMAINTENANCE_TRACKING_ALREADY_STARTEDmaintenanceTrackingMode du véhiculeréécrit les points de départ de toutes les échéances
Structure des saisons422 REFERENCE_NOT_FOUND sur une saison inconnueGET /seasonsle jeu de saisons est créé avec l'organisation ; l'API règle les multiplicateurs, pas la création ni la suppression de saison
Lieux gérés422 REFERENCE_INACTIVE sur un lieu désactivéGET /locationsnon bloquant : { address } libre, name facultatif, reste toujours possible
Blocage d'un client409 CUSTOMER_BLOCKED (BOOKING_REFUSED pour une clé partenaire)isBlocked de la fiche clientdécision du loueur ; son motif reste interne
Fiche entreprise du loueur409 CREDIT_NOTE_NOT_ISSUABLE à l'annulation ou au remboursementrefus nommé dans l'erreurinformations légales du loueur, à compléter dans Lexio
Trop-perçu d'une clé partenaire409 OVERPAYMENT_RESOLUTION_REQUIRED avec resolvableByKey: falsebalance de la locationdécision d'argent réservée au loueur

Exceptions publiées