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

# Fixer la quantité d’une option

> **Accès** : `rentals.write` · Fonctionnalité d’abonnement : `pricing.options` ([plans](https://docs.lexio.rent/authentification))

Fixe la quantité finale (1 à 100) d’une option standard sur une location `RESERVED` ou `IN_PROGRESS` : ligne créée si besoin, même quantité sans effet. Pour retirer la ligne : `DELETE`.

**Prix** : unités gardées à leur prix, ajoutées au tarif du jour, retirées au dernier prix vendu. Sur `IN_PROGRESS`, avenant si le changement est significatif (`effects.amendment`).

**Refus**
- 404 `resource: OPTION` : option inconnue ; 400 `not_applicable` : option conducteur (gérée dans Lexio).
- En hausse : `REFERENCE_INACTIVE` (désactivée), `OPTION_OUT_OF_SEASON`, `OPTION_QUANTITY_EXCEEDED` (au-delà du maximum), `OPTION_UNAVAILABLE` (stock insuffisant), `BOOKING_REFUSED` (contrat au mois).
- En baisse : `INVOICE_FINALIZED` (facture finalisée en comptabilité).
- `SERVICE_UNAVAILABLE` : vérification comptable indisponible, à rejouer.

**Aperçu et prix** : `?dryRun=true`, `expectedTotalTTC` (`PRICE_CHANGED`), `overpaymentResolution` (`OVERPAYMENT_RESOLUTION_REQUIRED`, `SEPA_DEBIT_PENDING`) : voir [Idempotence](https://docs.lexio.rent/idempotence).



## OpenAPI

````yaml /openapi.json put /rentals/{rentalId}/options/{optionId}
openapi: 3.1.0
info:
  title: API Lexio
  version: 1.0.1
  description: >-
    # API Lexio v1


    L’API Lexio permet à un loueur de véhicules, ou à une plateforme partenaire
    autorisée par lui, de chiffrer, réserver, suivre et administrer ses
    locations depuis un serveur. Chaque appel agit sur l’organisation Lexio d’un
    seul loueur.


    - **Adresse de base** : `https://api.lexio.rent/api/external/v1`

    - **Authentification** : `Authorization: Bearer lck_…`, une clé créée par le
    loueur dans Lexio.

    - **Format** : JSON en UTF-8 ; erreurs RFC 9457 avec un `code` stable.

    - **Spécification OpenAPI 3.1** :
    [https://docs.lexio.rent/openapi.json](https://docs.lexio.rent/openapi.json),
    à importer dans votre client HTTP ou à utiliser pour générer un client.

    - **Contact** (support technique, demande d’accès, organisation de test) :
    contact@lexio.rent.


    Vocabulaire : une **location** (`/rentals`) est un contrat de location d’un
    véhicule ; un **lieu** (`/locations`) est une adresse de départ ou de
    retour.


    ## Guides


    1. [Démarrage rapide](https://docs.lexio.rent/demarrage-rapide) : de la
    recherche d’un véhicule à l’annulation.

    2. [Authentification et scopes](https://docs.lexio.rent/authentification) :
    clés du loueur et clés partenaires, scopes, plans.

    3. [Montants et TVA](https://docs.lexio.rent/montants-et-tva) : HT, TTC,
    devises, caution et franchise.

    4. [Cycle de vie d’une location](https://docs.lexio.rent/cycle-de-vie) :
    statuts et actions possibles.

    5. [Limites de débit](https://docs.lexio.rent/limites),
    [Pagination](https://docs.lexio.rent/pagination), [Idempotence et
    reprise](https://docs.lexio.rent/idempotence).

    6. [Synchronisation par événements](https://docs.lexio.rent/synchronisation)
    : suivre les changements sans webhook.

    7. [Versions et évolutions](https://docs.lexio.rent/versions),
    [Erreurs](https://docs.lexio.rent/erreurs).

    8. [Intégration d’une plateforme de
    réservation](https://docs.lexio.rent/integration-broker) : parcours
    partenaire, paiement.

    9. [Ce qui se gère dans
    Lexio](https://docs.lexio.rent/ce-qui-se-gere-dans-lexio) et [Historique des
    versions](https://docs.lexio.rent/historique).
  contact:
    name: Support Lexio
    email: contact@lexio.rent
    url: https://docs.lexio.rent
servers:
  - url: https://api.lexio.rent/api/external/v1
    description: Production
security:
  - ApiKey: []
tags:
  - name: Organisation
    description: >-
      Réglages de l’organisation liée à la clé : devise, fuseau, TVA, horaires,
      règles de réservation.
  - name: Offre
    description: >-
      Disponibilités et devis : ce qui est réservable, à quel prix, avant de
      créer une location.
  - name: Locations
    description: >-
      Les contrats de location : création, lecture, modification de notes,
      suppression.
  - name: Modifications
    description: >-
      Changer les dates, le véhicule, la protection, le titulaire ou les options
      d’une location, ou l’annuler.
  - name: Départ et retour
    description: >-
      Remise des clés et retour du véhicule : kilométrage, carburant, photos,
      état des lieux.
  - name: Paiements
    description: Encaissements, cautions et remboursements enregistrés sur une location.
  - name: Événements
    description: >-
      Flux des changements à relire pour synchroniser votre système, sans
      webhook.
  - name: Clients
    description: Fiches des clients particuliers et entreprises.
  - name: Flotte
    description: Véhicules, leur archivage et leurs indisponibilités.
  - name: Catalogue
    description: >-
      Catégories, lieux, options, franchises, cautions et forfaits kilométriques
      proposés à la location.
  - name: Tarification
    description: Saisons, remises de durée, paliers de délai et réglages de prix.
  - name: Entretien
    description: Alertes et historique d’entretien des véhicules.
paths:
  /rentals/{rentalId}/options/{optionId}:
    put:
      tags:
        - Modifications
      summary: Fixer la quantité d’une option
      description: >-
        **Accès** : `rentals.write` · Fonctionnalité d’abonnement :
        `pricing.options` ([plans](https://docs.lexio.rent/authentification))


        Fixe la quantité finale (1 à 100) d’une option standard sur une location
        `RESERVED` ou `IN_PROGRESS` : ligne créée si besoin, même quantité sans
        effet. Pour retirer la ligne : `DELETE`.


        **Prix** : unités gardées à leur prix, ajoutées au tarif du jour,
        retirées au dernier prix vendu. Sur `IN_PROGRESS`, avenant si le
        changement est significatif (`effects.amendment`).


        **Refus**

        - 404 `resource: OPTION` : option inconnue ; 400 `not_applicable` :
        option conducteur (gérée dans Lexio).

        - En hausse : `REFERENCE_INACTIVE` (désactivée), `OPTION_OUT_OF_SEASON`,
        `OPTION_QUANTITY_EXCEEDED` (au-delà du maximum), `OPTION_UNAVAILABLE`
        (stock insuffisant), `BOOKING_REFUSED` (contrat au mois).

        - En baisse : `INVOICE_FINALIZED` (facture finalisée en comptabilité).

        - `SERVICE_UNAVAILABLE` : vérification comptable indisponible, à
        rejouer.


        **Aperçu et prix** : `?dryRun=true`, `expectedTotalTTC`
        (`PRICE_CHANGED`), `overpaymentResolution`
        (`OVERPAYMENT_RESOLUTION_REQUIRED`, `SEPA_DEBIT_PENDING`) : voir
        [Idempotence](https://docs.lexio.rent/idempotence).
      operationId: setRentalOptionQuantity
      parameters:
        - in: path
          name: rentalId
          schema:
            examples:
              - 9c2d7e4a-5b1f-4d3c-8a6e-0f1b2c3d4e5f
            type: string
            format: uuid
          required: true
          description: Identifiant de la location.
        - in: path
          name: optionId
          schema:
            examples:
              - 6a7b8c9d-0e1f-4a2b-9c3d-5e6f70819203
            type: string
            format: uuid
          required: true
          description: Identifiant de l’option.
        - in: query
          name: dryRun
          schema:
            description: 'true : aperçu, la même action annulée en fin de transaction.'
            type: string
            enum:
              - 'true'
              - 'false'
          description: 'true : aperçu, la même action annulée en fin de transaction.'
        - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            example:
              quantity: 2
              expectedTotalTTC: 332.4
            schema:
              type: object
              properties:
                quantity:
                  description: >-
                    Quantité finale de la ligne (0 → 400 too_small : pour
                    retirer, utiliser DELETE).
                  type: integer
                  minimum: 1
                  maximum: 100
                expectedTotalTTC:
                  description: >-
                    Total TTC affiché par l’aperçu (dryRun). Écart d’au moins
                    une unité mineure avec le total recalculé → 409
                    PRICE_CHANGED.
                  type: number
                overpaymentResolution:
                  description: >-
                    REFUND_PENDING : remboursement PENDING par virement du
                    trop-perçu ; NO_REFUND : le loueur le conserve. Exige le
                    scope payments.refund.
                  type: string
                  enum:
                    - REFUND_PENDING
                    - NO_REFUND
              required:
                - quantity
              additionalProperties: false
      responses:
        '200':
          description: Fixer la quantité d’une option
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Idempotent-Replayed:
              $ref: '#/components/headers/IdempotentReplayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Rental'
                  effects:
                    type: object
                    properties:
                      priceChange:
                        anyOf:
                          - $ref: '#/components/schemas/PriceChange'
                          - type: 'null'
                      optionLine:
                        description: >-
                          Ligne modifiée : les unités conservées gardent leur
                          prix figé, les unités ajoutées prennent le tarif du
                          jour.
                        type: object
                        properties:
                          optionId:
                            examples:
                              - 7c9e6679-7425-40de-944b-e07fc1f90ae7
                            type: string
                            format: uuid
                          previousQuantity:
                            type: integer
                            minimum: 0
                          newQuantity:
                            description: 0 après un retrait.
                            type: integer
                            minimum: 0
                          amountHT:
                            description: >-
                              Total HT de la ligne après la modification ; 0
                              après un retrait.
                            type: number
                          amountTTC:
                            description: >-
                              Total TTC de la ligne après la modification ; 0
                              après un retrait.
                            type: number
                        required:
                          - optionId
                          - previousQuantity
                          - newQuantity
                          - amountHT
                          - amountTTC
                      amendment:
                        anyOf:
                          - $ref: '#/components/schemas/AmendmentRef'
                          - type: 'null'
                      overpayment:
                        anyOf:
                          - $ref: '#/components/schemas/Overpayment'
                          - type: 'null'
                    required:
                      - priceChange
                      - optionLine
                      - amendment
                      - overpayment
                required:
                  - data
                  - effects
        '400':
          description: '`MALFORMED_REQUEST`, `VALIDATION_FAILED`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/MalformedRequestProblem'
                  - $ref: '#/components/schemas/ValidationFailedProblem'
        '401':
          description: >-
            `API_KEY_DISABLED`, `API_KEY_EXPIRED`, `API_KEY_INVALID`,
            `API_KEY_MISSING`, `API_KEY_REVOKED`
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            WWW-Authenticate:
              $ref: '#/components/headers/WwwAuthenticate'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ApiKeyDisabledProblem'
                  - $ref: '#/components/schemas/ApiKeyExpiredProblem'
                  - $ref: '#/components/schemas/ApiKeyInvalidProblem'
                  - $ref: '#/components/schemas/ApiKeyMissingProblem'
                  - $ref: '#/components/schemas/ApiKeyRevokedProblem'
        '403':
          description: >-
            `FEATURE_NOT_AVAILABLE`, `INSUFFICIENT_SCOPE`,
            `ORGANIZATION_SUSPENDED`
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/FeatureNotAvailableProblem'
                  - $ref: '#/components/schemas/InsufficientScopeProblem'
                  - $ref: '#/components/schemas/OrganizationSuspendedProblem'
        '404':
          description: '`NOT_FOUND`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/NotFoundProblem'
        '409':
          description: >-
            `BOOKING_REFUSED`, `IDEMPOTENCY_ALREADY_APPLIED`,
            `IDEMPOTENCY_IN_FLIGHT`, `INVOICE_FINALIZED`, `OPTION_UNAVAILABLE`,
            `OVERPAYMENT_RESOLUTION_REQUIRED`, `PRICE_CHANGED`, `RENTAL_BUSY`,
            `RENTAL_CHANGED`, `RENTAL_STATUS_NOT_ALLOWED`, `SEPA_DEBIT_PENDING`
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/BookingRefusedProblem'
                  - $ref: '#/components/schemas/IdempotencyAlreadyAppliedProblem'
                  - $ref: '#/components/schemas/IdempotencyInFlightProblem'
                  - $ref: '#/components/schemas/InvoiceFinalizedProblem'
                  - $ref: '#/components/schemas/OptionUnavailableProblem'
                  - $ref: '#/components/schemas/OverpaymentResolutionRequiredProblem'
                  - $ref: '#/components/schemas/PriceChangedProblem'
                  - $ref: '#/components/schemas/RentalBusyProblem'
                  - $ref: '#/components/schemas/RentalChangedProblem'
                  - $ref: '#/components/schemas/RentalStatusNotAllowedProblem'
                  - $ref: '#/components/schemas/SepaDebitPendingProblem'
        '413':
          description: '`PAYLOAD_TOO_LARGE`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PayloadTooLargeProblem'
        '415':
          description: '`UNSUPPORTED_MEDIA_TYPE`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/UnsupportedMediaTypeProblem'
        '422':
          description: >-
            `IDEMPOTENCY_KEY_REUSED`, `OPTION_OUT_OF_SEASON`,
            `OPTION_QUANTITY_EXCEEDED`, `REFERENCE_INACTIVE`
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/IdempotencyKeyReusedProblem'
                  - $ref: '#/components/schemas/OptionOutOfSeasonProblem'
                  - $ref: '#/components/schemas/OptionQuantityExceededProblem'
                  - $ref: '#/components/schemas/ReferenceInactiveProblem'
        '429':
          description: '`RATE_LIMITED`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/RateLimitedProblem'
        '500':
          description: '`INTERNAL_ERROR`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/InternalErrorProblem'
        '503':
          description: '`SERVICE_UNAVAILABLE`'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableProblem'
      security:
        - ApiKey: []
components:
  parameters:
    IdempotencyKeyRequired:
      name: Idempotency-Key
      in: header
      required: true
      example: 8b3e1d2c-4a5f-4c6b-9e7d-1f2a3b4c5d6e
      description: >-
        Clé unique de l’opération, réutilisée à chaque nouvel essai : un rejeu
        avec la même clé et le même corps renvoie la réponse initiale sans rien
        réécrire. Voir [Idempotence](https://docs.lexio.rent/idempotence).
        Facultative avec `?dryRun=true` sur les opérations qui l’acceptent.
      schema:
        type: string
        minLength: 1
        maxLength: 255
        pattern: ^[\x20-\x7E]+$
        examples:
          - 8b3e1d2c-4a5f-4c6b-9e7d-1f2a3b4c5d6e
  headers:
    XRequestId:
      description: Identifiant de la requête, à communiquer au support.
      schema:
        type: string
    RateLimitLimit:
      description: Plafond du seau de débit qui s’applique à la requête.
      schema:
        type: integer
        minimum: 0
    RateLimitRemaining:
      description: Requêtes encore permises dans la fenêtre en cours.
      schema:
        type: integer
        minimum: 0
    RateLimitReset:
      description: Secondes avant la remise à zéro de la fenêtre.
      schema:
        type: integer
        minimum: 0
    IdempotentReplayed:
      description: >-
        `true` quand la réponse est le rejeu d’une requête déjà traitée avec la
        même `Idempotency-Key`.
      schema:
        type: string
        enum:
          - 'true'
    WwwAuthenticate:
      description: >-
        Schéma d’authentification attendu (`Bearer`), avec
        `error="invalid_token"` pour une clé refusée.
      schema:
        type: string
    RetryAfter:
      description: Secondes à attendre avant de rejouer la requête.
      schema:
        type: integer
        minimum: 0
  schemas:
    Rental:
      description: >-
        Location, dans la même représentation pour la lecture, la liste et
        chaque écriture. Montants dans `currency`, voir [Montants et
        TVA](https://docs.lexio.rent/montants-et-tva).
      examples:
        - id: 9c2d7e4a-5b1f-4d3c-8a6e-0f1b2c3d4e5f
          number: LOC-2026.11-0042
          status: RESERVED
          source: PARTNER
          partnerCode: azur-voyages
          partnerReference: AV-884213
          period:
            startAt: '2026-11-10T10:00:00+01:00'
            endAt: '2026-11-15T10:00:00+01:00'
            timezone: Europe/Paris
            billedDays: 5
            durationMinutes: 7200
          actualStartAt: null
          actualEndAt: null
          vehicle:
            id: 3b1f5c2a-8d4e-4f6a-9b7c-2e5d8a1f4c63
            name: 208 Allure
            brand: Peugeot
            model: '208'
            vehicleType: CITY
            plate: AB-123-CD
            serialNumber: null
          customer:
            id: 7c4e2b9a-1f3d-4a6e-8b5c-9d0e1f2a3b4c
            isCompany: false
            firstName: Marie
            lastName: Martin
            companyName: null
            email: marie.martin@example.com
            phone: '+33612345678'
          pickupLocation:
            locationId: c41a9e3b-2d55-4b0f-8c11-0f3a7d6e9b42
            name: Agence Nice Gare
            address: 12 avenue Thiers, 06000 Nice
          returnLocation:
            locationId: null
            name: Hôtel Negresco
            address: 37 promenade des Anglais, 06000 Nice
          mileage:
            mileagePackageId: 5b7c9d1e-2f3a-4b5c-8d6e-7f8091a2b3c4
            name: 200 km/jour
            isUnlimited: false
            includedKm: 1000
            overageRatePerKmHT: 0.25
          deductible:
            deductibleId: 2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f
            name: Franchise réduite
            description: Reste à charge réduit en cas de sinistre.
            excessAmount: 500
          deposit:
            depositId: 4e5f6a7b-8c9d-4e0f-9a1b-3c4d5e6f7081
            name: Caution citadine
            depositAmount: 800
          options:
            - optionId: 6a7b8c9d-0e1f-4a2b-9c3d-5e6f70819203
              name: Siège enfant
              kind: STANDARD
              quantity: 1
          lines:
            - key: BASE
              label: Tarif de base
              refId: null
              quantity: 1
              unitPriceHT: 210
              unitPriceTTC: 252
              amountHT: 210
              amountTTC: 252
              ratePercent: null
            - key: DURATION_DISCOUNT
              label: Réduction durée 5 jours
              refId: null
              quantity: 1
              unitPriceHT: -10.5
              unitPriceTTC: -12.6
              amountHT: -10.5
              amountTTC: -12.6
              ratePercent: 5
            - key: MILEAGE
              label: Forfait 200 km/jour
              refId: null
              quantity: 1
              unitPriceHT: 0
              unitPriceTTC: 0
              amountHT: 0
              amountTTC: 0
              ratePercent: null
            - key: DEDUCTIBLE
              label: Franchise réduite
              refId: null
              quantity: 1
              unitPriceHT: 37.5
              unitPriceTTC: 45
              amountHT: 37.5
              amountTTC: 45
              ratePercent: null
            - key: OPTION
              label: Siège enfant
              refId: 6a7b8c9d-0e1f-4a2b-9c3d-5e6f70819203
              quantity: 1
              unitPriceHT: 20
              unitPriceTTC: 24
              amountHT: 20
              amountTTC: 24
              ratePercent: null
          promoCode: null
          currency: EUR
          vatPercent: 20
          isVatReverseCharge: false
          totalHT: 257
          vatAmount: 51.4
          totalTTC: 308.4
          balance:
            totalTTC: 308.4
            paidAmount: 0
            dueAmount: 308.4
            overpaidAmount: 0
          notes: Siège enfant à installer avant la remise.
          createdAt: '2026-11-02T09:15:02+01:00'
          updatedAt: '2026-11-02T09:15:02+01:00'
      type: object
      properties:
        id:
          examples:
            - 7c9e6679-7425-40de-944b-e07fc1f90ae7
          description: Identifiant de la location.
          type: string
          format: uuid
        number:
          description: >-
            Numéro de la location dans Lexio, unique dans l’organisation et
            jamais réattribué.
          type: string
        status:
          description: >-
            `PENDING_APPROVAL` : demande à approuver par le loueur ; `RESERVED`
            : réservée ; `IN_PROGRESS` : véhicule remis ; `COMPLETED` : véhicule
            rendu ; `CANCELLED` : annulée.
          type: string
          enum:
            - RESERVED
            - PENDING_APPROVAL
            - IN_PROGRESS
            - COMPLETED
            - CANCELLED
        source:
          description: >-
            Canal de vente : `ONLINE` (en ligne), `PHONE` (téléphone), `WALKIN`
            (sur place), `PARTNER` (partenaire, toute location créée par une clé
            partenaire), `OTHER`.
          type: string
          enum:
            - ONLINE
            - PHONE
            - WALKIN
            - PARTNER
            - OTHER
        partnerCode:
          description: >-
            Code partenaire de la clé qui a créé la location ; null hors
            partenaire.
          anyOf:
            - type: string
              maxLength: 50
            - type: 'null'
        partnerReference:
          description: >-
            Numéro de commande du partenaire, unique par code partenaire ; null
            si absent.
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
        period:
          $ref: '#/components/schemas/Period'
        actualStartAt:
          description: Départ réel (`pickup`) ; null tant que le véhicule n’est pas remis.
          anyOf:
            - examples:
                - '2026-11-10T10:00:00+01:00'
              type: string
              format: date-time
            - type: 'null'
        actualEndAt:
          description: Retour réel (`return`) ; null tant que le véhicule n’est pas rendu.
          anyOf:
            - examples:
                - '2026-11-10T10:00:00+01:00'
              type: string
              format: date-time
            - type: 'null'
        vehicle:
          $ref: '#/components/schemas/VehicleRef'
          description: Véhicule actuellement affecté à la location.
          examples:
            - id: 3b1f5c2a-8d4e-4f6a-9b7c-2e5d8a1f4c63
              name: 208 Allure
              brand: Peugeot
              model: '208'
              vehicleType: CITY
              plate: AB-123-CD
              serialNumber: null
        customer:
          description: Titulaire de la location.
          type: object
          properties:
            id:
              examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              description: Identifiant du client.
              type: string
              format: uuid
            isCompany:
              description: >-
                true : société ; false : particulier. Les champs de l’autre type
                valent null.
              type: boolean
            firstName:
              description: >-
                Prénom (particulier) ; null pour une société ou une fiche
                anonymisée.
              anyOf:
                - type: string
                - type: 'null'
            lastName:
              description: >-
                Nom de famille (particulier), publié en majuscules ; null pour
                une société ou une fiche anonymisée.
              anyOf:
                - type: string
                - type: 'null'
            companyName:
              description: Raison sociale (société) ; null pour un particulier.
              anyOf:
                - type: string
                - type: 'null'
            email:
              description: >-
                Email, en minuscules ; celui d’un particulier est unique pour un
                même `partnerCode`. null si absent.
              anyOf:
                - type: string
                - type: 'null'
            phone:
              description: >-
                Téléphone, au format international quand le pays est connu ;
                null si absent.
              anyOf:
                - type: string
                - type: 'null'
          required:
            - id
            - isCompany
            - firstName
            - lastName
            - companyName
            - email
            - phone
        pickupLocation:
          description: Lieu de départ ; null si non renseigné.
          anyOf:
            - $ref: '#/components/schemas/LocationRef'
            - type: 'null'
        returnLocation:
          description: Lieu de retour ; null si non renseigné.
          anyOf:
            - $ref: '#/components/schemas/LocationRef'
            - type: 'null'
        mileage:
          $ref: '#/components/schemas/Mileage'
        deductible:
          description: Franchise retenue ; null sans franchise.
          anyOf:
            - $ref: '#/components/schemas/DeductibleSnapshot'
            - type: 'null'
        deposit:
          description: Caution retenue ; null sans caution.
          anyOf:
            - $ref: '#/components/schemas/DepositSnapshot'
            - type: 'null'
        options:
          description: Options vendues ; leurs montants se lisent dans `lines`.
          maxItems: 50
          type: array
          items:
            $ref: '#/components/schemas/RentalOption'
        lines:
          description: >-
            Détail du prix, une ligne par règle appliquée, frais et dépassement
            kilométrique compris.
          maxItems: 200
          type: array
          items:
            $ref: '#/components/schemas/PriceLine'
        promoCode:
          description: Code promo utilisé ; null sans code.
          anyOf:
            - type: string
              maxLength: 50
            - type: 'null'
        currency:
          description: >-
            Devise de la location, figée à sa création : tous ses montants sont
            dans celle-ci.
          examples:
            - EUR
          type: string
          enum:
            - EUR
            - XPF
            - CHF
            - CAD
            - GBP
            - USD
            - XOF
        vatPercent:
          description: >-
            Taux de TVA appliqué, en pourcentage (20 = 20 %) ; 0 en
            autoliquidation ou pour une agence exonérée. Au plus 2 décimales.
          type: number
          minimum: 0
          maximum: 100
        isVatReverseCharge:
          description: >-
            true : autoliquidation de la TVA, `vatPercent` vaut 0 et `totalTTC`
            = `totalHT`.
          type: boolean
        totalHT:
          description: >-
            Total hors taxes ; fait foi. Égal à la somme des `lines[].amountHT`,
            sauf écart possible sur une location ancienne.
          type: number
        vatAmount:
          description: 'Montant de la TVA : `totalTTC − totalHT`.'
          type: number
        totalTTC:
          description: >-
            Total toutes taxes comprises, montant de la pièce : inchangé par une
            annulation, caution et franchise exclues. Fait foi ; égal à la somme
            des `lines[].amountTTC`, sauf écart possible sur une location
            ancienne.
          type: number
        balance:
          $ref: '#/components/schemas/Balance'
        notes:
          description: Note libre de la location ; null si vide.
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
        createdAt:
          examples:
            - '2026-11-10T10:00:00+01:00'
          description: Instant de création.
          type: string
          format: date-time
        updatedAt:
          examples:
            - '2026-11-10T10:00:00+01:00'
          description: Instant de la dernière modification.
          type: string
          format: date-time
      required:
        - id
        - number
        - status
        - source
        - partnerCode
        - partnerReference
        - period
        - actualStartAt
        - actualEndAt
        - vehicle
        - customer
        - pickupLocation
        - returnLocation
        - mileage
        - deductible
        - deposit
        - options
        - lines
        - promoCode
        - currency
        - vatPercent
        - isVatReverseCharge
        - totalHT
        - vatAmount
        - totalTTC
        - balance
        - notes
        - createdAt
        - updatedAt
    PriceChange:
      description: >-
        Totaux de la location avant puis après l’action, dans sa devise ; null
        si le total TTC ne change pas.
      examples:
        - previousTotalHT: 257
          previousTotalTTC: 308.4
          newTotalHT: 351.8
          newTotalTTC: 422.16
          differenceHT: 94.8
          differenceTTC: 113.76
      type: object
      properties:
        previousTotalHT:
          description: Total HT avant l’action.
          type: number
        previousTotalTTC:
          description: Total TTC avant l’action.
          type: number
        newTotalHT:
          description: Total HT après l’action.
          type: number
        newTotalTTC:
          description: >-
            Total TTC après l’action, à reprendre en `expectedTotalTTC` de
            l’appel réel.
          type: number
        differenceHT:
          description: '`newTotalHT − previousTotalHT`, signé.'
          type: number
        differenceTTC:
          description: '`newTotalTTC − previousTotalTTC`, signé.'
          type: number
      required:
        - previousTotalHT
        - previousTotalTTC
        - newTotalHT
        - newTotalTTC
        - differenceHT
        - differenceTTC
    AmendmentRef:
      description: >-
        Avenant créé par une modification significative d’une location
        `IN_PROGRESS` ; son document se lit par `GET
        /rentals/{rentalId}/amendments`.
      examples:
        - id: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
          number: AVT-LOC-2026.11-0042-001
      type: object
      properties:
        id:
          description: Avenant ; null en aperçu (`dryRun`).
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
        number:
          description: Numéro de l’avenant ; null en aperçu (`dryRun`).
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
      required:
        - id
        - number
    Overpayment:
      description: Trop-perçu créé par l’action et sa résolution.
      examples:
        - overpaidAmount: 24
          resolution: REFUND_PENDING
          resolvableByKey: true
          refundPaymentId: b7c8d9e0-f1a2-4b3c-8d4e-5f6a7b8c9d0e
      type: object
      properties:
        overpaidAmount:
          description: >-
            Trop-perçu créé par l’action : net encaissé hors caution, moins les
            remboursements en attente, au-delà du nouveau total TTC. Un
            trop-perçu antérieur n’est jamais redemandé.
          type: number
          exclusiveMinimum: 0
        resolution:
          description: >-
            Résolution appliquée ; null seulement en aperçu sans
            `overpaymentResolution`, que l’appel réel exigera.
          anyOf:
            - description: >-
                REFUND_PENDING : remboursement PENDING par virement du
                trop-perçu ; NO_REFUND : le loueur le conserve. Exige le scope
                payments.refund.
              type: string
              enum:
                - REFUND_PENDING
                - NO_REFUND
            - type: 'null'
        resolvableByKey:
          description: >-
            true si la clé a le scope `payments.refund` et peut résoudre le
            trop-perçu ; sinon le loueur le traite dans Lexio.
          type: boolean
        refundPaymentId:
          description: >-
            Remboursement en attente (`PENDING`) créé par `REFUND_PENDING` ;
            null sinon, et en aperçu.
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
      required:
        - overpaidAmount
        - resolution
        - resolvableByKey
        - refundPaymentId
    MalformedRequestProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/malformed-request
        title:
          type: string
          const: Corps de requête illisible
        status:
          type: number
          const: 400
        code:
          type: string
          const: MALFORMED_REQUEST
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ValidationFailedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/validation-failed
        title:
          type: string
          const: Requête invalide
        status:
          type: number
          const: 400
        code:
          type: string
          const: VALIDATION_FAILED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        errors:
          minItems: 1
          maxItems: 100
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              code:
                type: string
                enum:
                  - required
                  - invalid_type
                  - invalid_format
                  - invalid_value
                  - too_small
                  - too_big
                  - too_many_decimals
                  - out_of_range
                  - unknown_field
                  - null_not_allowed
                  - empty_string
                  - empty_patch
                  - mutually_exclusive
                  - not_applicable
                  - duplicate
                  - end_before_start
                  - date_in_past
                  - nonexistent_local_time
                  - offset_not_allowed
                  - offset_required
                  - upload_expired
                  - upload_incomplete
                  - upload_conflict
              detail:
                type: string
            required:
              - pointer
              - code
              - detail
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - errors
    ApiKeyDisabledProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/api-key-disabled
        title:
          type: string
          const: Clé API désactivée
        status:
          type: number
          const: 401
        code:
          type: string
          const: API_KEY_DISABLED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ApiKeyExpiredProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/api-key-expired
        title:
          type: string
          const: Clé API expirée
        status:
          type: number
          const: 401
        code:
          type: string
          const: API_KEY_EXPIRED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ApiKeyInvalidProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/api-key-invalid
        title:
          type: string
          const: Clé API invalide
        status:
          type: number
          const: 401
        code:
          type: string
          const: API_KEY_INVALID
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ApiKeyMissingProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/api-key-missing
        title:
          type: string
          const: Clé API absente
        status:
          type: number
          const: 401
        code:
          type: string
          const: API_KEY_MISSING
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ApiKeyRevokedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/api-key-revoked
        title:
          type: string
          const: Clé API révoquée
        status:
          type: number
          const: 401
        code:
          type: string
          const: API_KEY_REVOKED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    FeatureNotAvailableProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/feature-not-available
        title:
          type: string
          const: Fonctionnalité non incluse
        status:
          type: number
          const: 403
        code:
          type: string
          const: FEATURE_NOT_AVAILABLE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        feature:
          type: string
          minLength: 1
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - feature
    InsufficientScopeProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/insufficient-scope
        title:
          type: string
          const: Scope insuffisant
        status:
          type: number
          const: 403
        code:
          type: string
          const: INSUFFICIENT_SCOPE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        requiredScopes:
          minItems: 1
          maxItems: 20
          type: array
          items:
            type: string
            enum:
              - offers.read
              - quotes.write
              - rentals.read
              - rentals.write
              - rentals.operate
              - rentals.delete
              - payments.write
              - payments.refund
              - customers.read
              - customers.write
              - customers.delete
              - vehicles.read
              - vehicles.write
              - vehicles.delete
              - catalog.read
              - catalog.write
              - pricing.read
              - pricing.write
              - maintenance.read
              - maintenance.write
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - requiredScopes
    OrganizationSuspendedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/organization-suspended
        title:
          type: string
          const: Organisation suspendue
        status:
          type: number
          const: 403
        code:
          type: string
          const: ORGANIZATION_SUSPENDED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    NotFoundProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/not-found
        title:
          type: string
          const: Ressource introuvable
        status:
          type: number
          const: 404
        code:
          type: string
          const: NOT_FOUND
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        resource:
          type: string
          enum:
            - RENTAL
            - RENTAL_OPTION
            - QUOTE
            - PAYMENT
            - INVOICE
            - PHOTO
            - AMENDMENT
            - INSPECTION
            - CUSTOMER
            - VEHICLE
            - VEHICLE_BLOCK
            - CATEGORY
            - OPTION
            - DEDUCTIBLE
            - DEPOSIT
            - MILEAGE_PACKAGE
            - LOCATION
            - SEASON
            - SEASON_CALENDAR_MONTH
            - DURATION_DISCOUNT
            - LEAD_TIME_TIER
            - MAINTENANCE_RECORD
            - MAINTENANCE_OPERATION
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - resource
    BookingRefusedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/booking-refused
        title:
          type: string
          const: Réservation refusée
        status:
          type: number
          const: 409
        code:
          type: string
          const: BOOKING_REFUSED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    IdempotencyAlreadyAppliedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/idempotency-already-applied
        title:
          type: string
          const: Écriture déjà appliquée
        status:
          type: number
          const: 409
        code:
          type: string
          const: IDEMPOTENCY_ALREADY_APPLIED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        resourceId:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - resourceId
    IdempotencyInFlightProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/idempotency-in-flight
        title:
          type: string
          const: Requête identique en cours
        status:
          type: number
          const: 409
        code:
          type: string
          const: IDEMPOTENCY_IN_FLIGHT
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    InvoiceFinalizedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/invoice-finalized
        title:
          type: string
          const: Facture finalisée
        status:
          type: number
          const: 409
        code:
          type: string
          const: INVOICE_FINALIZED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    OptionUnavailableProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/option-unavailable
        title:
          type: string
          const: Option en rupture
        status:
          type: number
          const: 409
        code:
          type: string
          const: OPTION_UNAVAILABLE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        optionId:
          type: string
          format: uuid
        availableQuantity:
          type: integer
          minimum: 0
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - optionId
        - availableQuantity
    OverpaymentResolutionRequiredProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/overpayment-resolution-required
        title:
          type: string
          const: Trop-perçu à résoudre
        status:
          type: number
          const: 409
        code:
          type: string
          const: OVERPAYMENT_RESOLUTION_REQUIRED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        overpaidAmount:
          type: number
        resolvableByKey:
          type: boolean
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - overpaidAmount
        - resolvableByKey
    PriceChangedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/price-changed
        title:
          type: string
          const: Prix modifié
        status:
          type: number
          const: 409
        code:
          type: string
          const: PRICE_CHANGED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        expectedTotalTTC:
          type: number
        currentTotalTTC:
          type: number
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - expectedTotalTTC
        - currentTotalTTC
    RentalBusyProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/rental-busy
        title:
          type: string
          const: Location occupée
        status:
          type: number
          const: 409
        code:
          type: string
          const: RENTAL_BUSY
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    RentalChangedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/rental-changed
        title:
          type: string
          const: Location modifiée entre-temps
        status:
          type: number
          const: 409
        code:
          type: string
          const: RENTAL_CHANGED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    RentalStatusNotAllowedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/rental-status-not-allowed
        title:
          type: string
          const: Statut de la location incompatible
        status:
          type: number
          const: 409
        code:
          type: string
          const: RENTAL_STATUS_NOT_ALLOWED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        errors:
          maxItems: 100
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              code:
                type: string
                enum:
                  - required
                  - invalid_type
                  - invalid_format
                  - invalid_value
                  - too_small
                  - too_big
                  - too_many_decimals
                  - out_of_range
                  - unknown_field
                  - null_not_allowed
                  - empty_string
                  - empty_patch
                  - mutually_exclusive
                  - not_applicable
                  - duplicate
                  - end_before_start
                  - date_in_past
                  - nonexistent_local_time
                  - offset_not_allowed
                  - offset_required
                  - upload_expired
                  - upload_incomplete
                  - upload_conflict
              detail:
                type: string
            required:
              - pointer
              - code
              - detail
        rentalStatus:
          type: string
          enum:
            - RESERVED
            - PENDING_APPROVAL
            - IN_PROGRESS
            - COMPLETED
            - CANCELLED
        allowedStatuses:
          maxItems: 10
          type: array
          items:
            type: string
            enum:
              - RESERVED
              - PENDING_APPROVAL
              - IN_PROGRESS
              - COMPLETED
              - CANCELLED
        action:
          type: string
          enum:
            - CANCEL
            - PICKUP
            - RETURN
            - RESCHEDULE
            - CHANGE_VEHICLE
            - CHANGE_COVERAGE
            - CHANGE_CUSTOMER
            - SET_OPTION_QUANTITY
            - REMOVE_OPTION
            - EDIT_NOTES
            - EDIT_LOCATIONS
            - DELETE
            - ADD_PAYMENT
            - REFUND
            - DELETE_PAYMENT
            - UPLOAD_PHOTO
            - DELETE_PHOTO
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - rentalStatus
        - allowedStatuses
        - action
    SepaDebitPendingProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/sepa-debit-pending
        title:
          type: string
          const: Prélèvement SEPA en cours
        status:
          type: number
          const: 409
        code:
          type: string
          const: SEPA_DEBIT_PENDING
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        pendingDebitAmount:
          type: number
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - pendingDebitAmount
    PayloadTooLargeProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/payload-too-large
        title:
          type: string
          const: Corps trop volumineux
        status:
          type: number
          const: 413
        code:
          type: string
          const: PAYLOAD_TOO_LARGE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        maxBytes:
          type: integer
          minimum: 1
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - maxBytes
    UnsupportedMediaTypeProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/unsupported-media-type
        title:
          type: string
          const: Type de contenu non pris en charge
        status:
          type: number
          const: 415
        code:
          type: string
          const: UNSUPPORTED_MEDIA_TYPE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        accepted:
          minItems: 1
          maxItems: 10
          type: array
          items:
            type: string
            minLength: 1
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - accepted
    IdempotencyKeyReusedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/idempotency-key-reused
        title:
          type: string
          const: Clé d’idempotence réutilisée
        status:
          type: number
          const: 422
        code:
          type: string
          const: IDEMPOTENCY_KEY_REUSED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    OptionOutOfSeasonProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/option-out-of-season
        title:
          type: string
          const: Option hors saison
        status:
          type: number
          const: 422
        code:
          type: string
          const: OPTION_OUT_OF_SEASON
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        errors:
          maxItems: 100
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              code:
                type: string
                enum:
                  - required
                  - invalid_type
                  - invalid_format
                  - invalid_value
                  - too_small
                  - too_big
                  - too_many_decimals
                  - out_of_range
                  - unknown_field
                  - null_not_allowed
                  - empty_string
                  - empty_patch
                  - mutually_exclusive
                  - not_applicable
                  - duplicate
                  - end_before_start
                  - date_in_past
                  - nonexistent_local_time
                  - offset_not_allowed
                  - offset_required
                  - upload_expired
                  - upload_incomplete
                  - upload_conflict
              detail:
                type: string
            required:
              - pointer
              - code
              - detail
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    OptionQuantityExceededProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/option-quantity-exceeded
        title:
          type: string
          const: Quantité d’option dépassée
        status:
          type: number
          const: 422
        code:
          type: string
          const: OPTION_QUANTITY_EXCEEDED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        errors:
          maxItems: 100
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              code:
                type: string
                enum:
                  - required
                  - invalid_type
                  - invalid_format
                  - invalid_value
                  - too_small
                  - too_big
                  - too_many_decimals
                  - out_of_range
                  - unknown_field
                  - null_not_allowed
                  - empty_string
                  - empty_patch
                  - mutually_exclusive
                  - not_applicable
                  - duplicate
                  - end_before_start
                  - date_in_past
                  - nonexistent_local_time
                  - offset_not_allowed
                  - offset_required
                  - upload_expired
                  - upload_incomplete
                  - upload_conflict
              detail:
                type: string
            required:
              - pointer
              - code
              - detail
        maxQuantity:
          type: integer
          minimum: 0
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - maxQuantity
    ReferenceInactiveProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/reference-inactive
        title:
          type: string
          const: Référence inactive
        status:
          type: number
          const: 422
        code:
          type: string
          const: REFERENCE_INACTIVE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        errors:
          minItems: 1
          maxItems: 100
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              code:
                type: string
                enum:
                  - required
                  - invalid_type
                  - invalid_format
                  - invalid_value
                  - too_small
                  - too_big
                  - too_many_decimals
                  - out_of_range
                  - unknown_field
                  - null_not_allowed
                  - empty_string
                  - empty_patch
                  - mutually_exclusive
                  - not_applicable
                  - duplicate
                  - end_before_start
                  - date_in_past
                  - nonexistent_local_time
                  - offset_not_allowed
                  - offset_required
                  - upload_expired
                  - upload_incomplete
                  - upload_conflict
              detail:
                type: string
            required:
              - pointer
              - code
              - detail
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - errors
    RateLimitedProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/rate-limited
        title:
          type: string
          const: Trop de requêtes
        status:
          type: number
          const: 429
        code:
          type: string
          const: RATE_LIMITED
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        limit:
          type: string
          enum:
            - PRE_AUTH
            - PER_KEY
            - WRITE
            - QUOTE
        windowSeconds:
          type: integer
          minimum: 1
        retryAfter:
          type: integer
          minimum: 0
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - limit
        - windowSeconds
        - retryAfter
    InternalErrorProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/internal-error
        title:
          type: string
          const: Erreur interne
        status:
          type: number
          const: 500
        code:
          type: string
          const: INTERNAL_ERROR
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
    ServiceUnavailableProblem:
      type: object
      properties:
        type:
          type: string
          const: https://api.lexio.rent/errors/service-unavailable
        title:
          type: string
          const: Service momentanément indisponible
        status:
          type: number
          const: 503
        code:
          type: string
          const: SERVICE_UNAVAILABLE
        detail:
          type: string
        instance:
          type: string
        requestId:
          type: string
        dependency:
          type: string
          enum:
            - PAYMENT_PROVIDER
            - FILE_STORAGE
            - ACCOUNTING
            - EMAIL
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - requestId
        - dependency
    Period:
      description: Période contractuelle, bornes à l’heure de l’agence.
      examples:
        - startAt: '2026-11-10T10:00:00+01:00'
          endAt: '2026-11-15T10:00:00+01:00'
          timezone: Europe/Paris
          billedDays: 5
          durationMinutes: 7200
      type: object
      properties:
        startAt:
          examples:
            - '2026-11-10T10:00:00+01:00'
          description: Début contractuel, à l’heure de l’agence.
          type: string
          format: date-time
        endAt:
          examples:
            - '2026-11-10T10:00:00+01:00'
          description: Fin contractuelle, à l’heure de l’agence.
          type: string
          format: date-time
        timezone:
          description: Fuseau horaire IANA de l’agence.
          examples:
            - Europe/Paris
          type: string
          minLength: 1
        billedDays:
          description: >-
            Jours facturés : tranches de 24 h entamées, sans compter une
            dernière tranche d’au plus `toleranceHours` heures (`GET
            /organization`) ; 1 au minimum.
          type: integer
          minimum: 0
        durationMinutes:
          description: Durée exacte entre `startAt` et `endAt`, en minutes.
          type: integer
          minimum: 0
      required:
        - startAt
        - endAt
        - timezone
        - billedDays
        - durationMinutes
    VehicleRef:
      description: Véhicule, vue réduite de `GET /vehicles/{vehicleId}`.
      examples:
        - id: 3b1f5c2a-8d4e-4f6a-9b7c-2e5d8a1f4c63
          name: 208 Allure
          brand: Peugeot
          model: '208'
          vehicleType: CITY
          plate: AB-123-CD
          serialNumber: null
      type: object
      properties:
        id:
          examples:
            - 7c9e6679-7425-40de-944b-e07fc1f90ae7
          description: Identifiant du véhicule.
          type: string
          format: uuid
        name:
          description: >-
            Nom d’usage donné par l’agence (ex. « 208 blanche ») ; null si
            absent.
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
        brand:
          description: Marque (ex. Peugeot).
          type: string
          maxLength: 50
        model:
          description: Modèle (ex. 208).
          type: string
          maxLength: 50
        vehicleType:
          description: 'Type de véhicule : il fixe la famille et les champs applicables.'
          type: string
          enum:
            - CITY
            - COMPACT
            - CROSSOVER
            - SEDAN
            - BREAK
            - SUV
            - OFF_ROAD
            - PICKUP
            - MINIVAN
            - VAN
            - UTILITY
            - COUPE
            - CONVERTIBLE
            - SPORT
            - LUXURY
            - MOTORCYCLE
            - SCOOTER
        plate:
          description: >-
            Immatriculation, en majuscules ; null si le véhicule n’en a pas. Une
            plaque ou un numéro de série est toujours présent.
          anyOf:
            - type: string
            - type: 'null'
        serialNumber:
          description: >-
            Numéro de série (deux-roues non immatriculé, par exemple) ; null si
            absent.
          anyOf:
            - type: string
            - type: 'null'
      required:
        - id
        - name
        - brand
        - model
        - vehicleType
        - plate
        - serialNumber
    LocationRef:
      description: >-
        Lieu de départ ou de retour, copié à l’enregistrement : une modification
        ultérieure du catalogue ne le change pas.
      examples:
        - locationId: c41a9e3b-2d55-4b0f-8c11-0f3a7d6e9b42
          name: Agence Nice Gare
          address: 12 avenue Thiers, 06000 Nice
      type: object
      properties:
        locationId:
          description: Lieu du catalogue (`GET /locations`) ; null pour une adresse libre.
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
        name:
          description: Nom du lieu, copié à l’enregistrement ; null si aucun.
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
        address:
          description: Adresse, copiée à l’enregistrement ; null si aucune.
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
      required:
        - locationId
        - name
        - address
    Mileage:
      description: Kilométrage inclus et prix du dépassement.
      examples:
        - mileagePackageId: 5b7c9d1e-2f3a-4b5c-8d6e-7f8091a2b3c4
          name: 200 km/jour
          isUnlimited: false
          includedKm: 1000
          overageRatePerKmHT: 0.25
      type: object
      properties:
        mileagePackageId:
          description: >-
            Forfait kilométrique du catalogue (`GET /mileage-packages`) ; null
            sans forfait.
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
        name:
          description: Nom du forfait ; null sans forfait.
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
        isUnlimited:
          description: >-
            true : aucun plafond ; `includedKm` et `overageRatePerKmHT` valent
            alors null.
          type: boolean
        includedKm:
          description: >-
            Kilomètres inclus pour toute la période, pas par jour ; null si
            illimité.
          anyOf:
            - type: integer
              minimum: 0
            - type: 'null'
        overageRatePerKmHT:
          description: >-
            Prix HT de chaque kilomètre au-delà de `includedKm`, facturé au
            retour ; null si illimité ou sans tarif de dépassement.
          anyOf:
            - type: number
              minimum: 0
              maximum: 999999.9999
              description: Au plus 4 décimales.
            - type: 'null'
      required:
        - mileagePackageId
        - name
        - isUnlimited
        - includedKm
        - overageRatePerKmHT
    DeductibleSnapshot:
      description: Franchise retenue, figée au moment du calcul.
      examples:
        - deductibleId: 2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f
          name: Franchise réduite
          description: Reste à charge réduit en cas de sinistre.
          excessAmount: 500
      type: object
      properties:
        deductibleId:
          description: >-
            Franchise du catalogue (`GET /deductibles`) ; null si elle a été
            supprimée depuis.
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
        name:
          description: Nom de la franchise ; null si elle a été supprimée depuis.
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
        description:
          description: Description de la franchise ; null si absente.
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
        excessAmount:
          description: >-
            Reste à charge du client en cas de sinistre, tel que fixé par le
            loueur, sans TVA appliquée. Jamais facturé ni compris dans les
            totaux : le prix de la franchise retenue est la ligne `DEDUCTIBLE`
            de `lines`.
          type: number
          minimum: 0
      required:
        - deductibleId
        - name
        - description
        - excessAmount
    DepositSnapshot:
      description: Caution retenue, figée au moment du calcul.
      examples:
        - depositId: 4e5f6a7b-8c9d-4e0f-9a1b-3c4d5e6f7081
          name: Caution citadine
          depositAmount: 800
      type: object
      properties:
        depositId:
          description: >-
            Caution du catalogue (`GET /deposits`) ; null si elle a été
            supprimée depuis.
          anyOf:
            - examples:
                - 7c9e6679-7425-40de-944b-e07fc1f90ae7
              type: string
              format: uuid
            - type: 'null'
        name:
          description: Nom de la caution ; null si elle a été supprimée depuis.
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
        depositAmount:
          description: >-
            Caution demandée au client, telle que fixée par le loueur, sans TVA
            appliquée. Hors `totalTTC` et hors `balance` : elle s’encaisse à
            part (paiement `DEPOSIT`).
          type: number
          minimum: 0
      required:
        - depositId
        - name
        - depositAmount
    RentalOption:
      description: >-
        Option vendue. Son prix se lit dans `lines` (ligne `OPTION` dont `refId`
        = `optionId`).
      examples:
        - optionId: 6a7b8c9d-0e1f-4a2b-9c3d-5e6f70819203
          name: Siège enfant
          kind: STANDARD
          quantity: 1
      type: object
      properties:
        optionId:
          examples:
            - 7c9e6679-7425-40de-944b-e07fc1f90ae7
          description: Option du catalogue (`GET /options`).
          type: string
          format: uuid
        name:
          description: Nom de l’option.
          type: string
          maxLength: 200
        kind:
          description: >-
            `STANDARD` : option du catalogue ; `ADDITIONAL_DRIVER` : conducteur
            additionnel ; `YOUNG_DRIVER` : majoration jeune conducteur.
          type: string
          enum:
            - STANDARD
            - ADDITIONAL_DRIVER
            - YOUNG_DRIVER
        quantity:
          description: Quantité vendue.
          type: integer
          minimum: 1
      required:
        - optionId
        - name
        - kind
        - quantity
    PriceLine:
      description: Ligne de prix d’une offre, d’un devis ou d’une location.
      examples:
        - key: OPTION
          label: Siège enfant
          refId: 6a7b8c9d-0e1f-4a2b-9c3d-5e6f70819203
          quantity: 1
          unitPriceHT: 20
          unitPriceTTC: 24
          amountHT: 20
          amountTTC: 24
          ratePercent: null
      type: object
      properties:
        key:
          description: >-
            Règle qui a produit la ligne : `BASE` (prix de location),
            `LEAD_TIME_ADJUSTMENT` (délai de réservation), `DURATION_DISCOUNT`
            (remise de durée), `COMMERCIAL_DISCOUNT` (remise commerciale),
            `WEEKEND_SURCHARGE` et `SHORT_DURATION_SURCHARGE` (majorations),
            `MILEAGE` (forfait kilométrique), `DEDUCTIBLE` (prix de la franchise
            retenue), `OPTION`, `CHARGE` (frais ou remise saisis), `PROMO` (code
            promo), `MILEAGE_OVERAGE` (dépassement kilométrique au retour),
            `MODIFICATION` (écart de prix d’une modification de la location).
          type: string
          enum:
            - BASE
            - LEAD_TIME_ADJUSTMENT
            - DURATION_DISCOUNT
            - COMMERCIAL_DISCOUNT
            - WEEKEND_SURCHARGE
            - SHORT_DURATION_SURCHARGE
            - MILEAGE
            - DEDUCTIBLE
            - OPTION
            - CHARGE
            - PROMO
            - MILEAGE_OVERAGE
            - MODIFICATION
        label:
          description: Libellé affichable ; ne pas l’analyser, lire `key`.
          type: string
        refId:
          description: >-
            Élément à l’origine de la ligne : `optionId` pour `OPTION`,
            identifiant du frais pour `CHARGE` et `MILEAGE_OVERAGE` d’une
            location ; null sinon.
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
        quantity:
          description: Nombre d’exemplaires (option) ; 1 pour les autres lignes.
          type: integer
          minimum: 1
        unitPriceHT:
          description: >-
            Prix HT d’un exemplaire pour toute la période (`OPTION`) ; égal à
            `amountHT` sinon.
          type: number
        unitPriceTTC:
          description: >-
            Prix TTC d’un exemplaire pour toute la période (`OPTION`) ; égal à
            `amountTTC` sinon.
          type: number
        amountHT:
          description: 'Montant HT de la ligne, signé : négatif pour une remise.'
          type: number
        amountTTC:
          description: 'Montant TTC de la ligne, signé : négatif pour une remise.'
          type: number
        ratePercent:
          description: >-
            Pourcentage appliqué (20 = 20 %) pour une remise de durée, une
            majoration, une franchise ou un forfait tarifés en pourcentage ;
            null pour les autres lignes et pour un montant saisi ou offert.
          anyOf:
            - type: number
              minimum: 0
              maximum: 100
              description: Au plus 2 décimales.
            - type: 'null'
      required:
        - key
        - label
        - refId
        - quantity
        - unitPriceHT
        - unitPriceTTC
        - amountHT
        - amountTTC
        - ratePercent
    Balance:
      description: Solde de la location dans sa devise ; la caution n’y entre jamais.
      examples:
        - totalTTC: 308.4
          paidAmount: 0
          dueAmount: 308.4
          overpaidAmount: 0
      type: object
      properties:
        totalTTC:
          description: 'Montant exigible : `totalTTC` de la location, 0 si elle est annulée.'
          type: number
          minimum: 0
        paidAmount:
          description: >-
            Net encaissé : paiements validés moins remboursements validés,
            caution exclue.
          type: number
        dueAmount:
          description: 'Reste à payer : `totalTTC − paidAmount`, 0 au minimum.'
          type: number
          minimum: 0
        overpaidAmount:
          description: >-
            Trop-perçu : `paidAmount − totalTTC`, 0 au minimum ; à rembourser ou
            à conserver par le loueur.
          type: number
          minimum: 0
      required:
        - totalTTC
        - paidAmount
        - dueAmount
        - overpaidAmount
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: lck_…
      description: >-
        Clé API `lck_…` créée dans Lexio (Paramètres → Développeur), envoyée en
        `Authorization: Bearer`. Voir
        [Authentification](https://docs.lexio.rent/authentification).

````

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