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

# car-search

> Search live car rental offers

Search live car rental availability. `pick_up` names exactly one of an `airport_code` (IATA), a free-text `place` (resolved server-side, ambiguous text returns `candidates` to retry with), or `geo` coordinates (round-trip only). Date-times are branch-local `YYYY-MM-DDTHH:MM:SS` with no timezone. Omit `drop_off` to return the car to the pick-up branch, setting `drop_off_date_time`. Each offer's `offer_id` is a trip item token: pass it verbatim to `POST /v1/trip` as `trip_item_token` to add the rental to a cart, then check out as normal. `price.pay_now` is the only amount Jinko charges, `due_at_desk` is collected by the rental desk locally.


## OpenAPI

````yaml api-reference/public-api.yaml POST /v1/car_search
openapi: 3.0.0
info:
  title: Jinko Public API
  version: 0.5.0
  description: >-
    Curated public REST surface for Jinko. Authenticated with jnk_ API keys. See
    https://docs.gojinko.com for guides.


    ### Per-end-user attribution


    On booking calls you may send an optional `X-End-User-Id` request header to
    attribute the booking to one of your own end users (for per-end-user
    attribution and rate-limiting). The value is an **opaque, tenant-scoped**
    identifier that you choose — not a Jinko account id. Omit it to book as the
    tenant. WorkOS-shaped values (prefixed `user_` or `org_`) are rejected.
servers: []
security: []
paths:
  /v1/car_search:
    post:
      tags:
        - Cars
      summary: Search live car rental offers
      description: >-
        Search live car rental availability. `pick_up` names exactly one of an
        `airport_code` (IATA), a free-text `place` (resolved server-side —
        ambiguous text returns `candidates` to retry with), or `geo` coordinates
        (round-trip only). Date-times are branch-local `YYYY-MM-DDTHH:MM:SS`
        with no timezone. Omit `drop_off` to return the car to the pick-up
        branch, setting `drop_off_date_time`. Each offer's `offer_id` is a trip
        item token: pass it verbatim to `POST /v1/trip` as `trip_item_token` to
        add the rental to a cart, then check out as normal. `price.pay_now` is
        the only amount Jinko charges — `due_at_desk` is collected by the rental
        desk locally.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarSearchRequest'
      responses:
        '200':
          description: Bookable car rental offers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CarSearchResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: BAD_REQUEST
                  message: Malformed JSON in request body.
                  doc_url: https://docs.gojinko.com/concepts/errors
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: AUTH_REQUIRED
                  message: Invalid or expired API key.
                  doc_url: https://docs.gojinko.com/api-reference/authentication
        '402':
          description: Payment required — organization balance exhausted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: PAYMENT_REQUIRED
                  message: >-
                    Insufficient balance — this call costs $0.0150 and your
                    organization has $0.0000 available. Top up at
                    https://dashboard.gojinko.com/developers/billing/topup
                  doc_url: https://docs.gojinko.com/concepts/errors
        '409':
          description: The operation conflicts with the current state of the resource
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: CONFLICT
                  message: an exchange is already in progress for this booking
                  doc_url: https://docs.gojinko.com/concepts/errors
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: BAD_REQUEST
                  message: >-
                    origins: origins is required; trip_type: trip_type is
                    required
                  doc_url: https://docs.gojinko.com/concepts/errors
        '429':
          description: Rate limit or quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: RATE_LIMITED
                  message: Rate limit or quota exceeded.
                  doc_url: https://docs.gojinko.com/concepts/errors
        '502':
          description: The travel provider rejected the request, or an upstream call failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UPSTREAM_REJECTED
                  message: >-
                    sabre-rest BargainFinderMaxRQ failed with status 400: 27131
                    - Number of connection locations exceeds maximum allowed
                  doc_url: https://docs.gojinko.com/concepts/errors
        '503':
          description: No travel provider can serve the request right now
          headers:
            Retry-After:
              description: >-
                Seconds to wait before retrying, forwarded verbatim from the
                upstream service. Absent when the upstream named no interval.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UPSTREAM_UNAVAILABLE
                  message: >-
                    All flight providers are temporarily unable to serve this
                    search. Please retry later. Provider reasons: sabre-rest:
                    provider temporarily closed; travelfusion: quota exhausted
                  doc_url: https://docs.gojinko.com/concepts/errors
        '504':
          description: The travel provider did not answer in time
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UPSTREAM_TIMEOUT
                  message: sabre-rest BargainFinderMaxRQ timed out after 30s
                  doc_url: https://docs.gojinko.com/concepts/errors
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
components:
  schemas:
    CarSearchRequest:
      type: object
      properties:
        pick_up:
          $ref: '#/components/schemas/CarPickUp'
        drop_off:
          $ref: '#/components/schemas/CarDropOff'
        drop_off_date_time:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          description: >-
            Drop-off date-time for a round trip, branch-local. Required when
            `drop_off` is omitted.
          example: '2026-09-15T10:00:00'
        driver_age:
          type: integer
          minimum: 18
          maximum: 99
          description: >-
            Driver's age at pick-up (18-99). Pricing and availability are
            age-dependent.
          example: 30
        residence_country:
          type: string
          pattern: ^[A-Za-z]{2}$
          description: >-
            Driver's country of residence, ISO 3166-1 alpha-2. Rates and
            inclusions vary by residence.
          example: FR
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: ISO 4217 display currency. Defaults to USD.
          example: EUR
        lang:
          type: string
          description: BCP-47 language tag for vehicle and branch text.
          example: en-gb
        intent:
          $ref: '#/components/schemas/IntentInput'
      required:
        - pick_up
        - driver_age
        - residence_country
      description: >-
        `pick_up` names exactly one of `airport_code`, `place` or `geo`, and a
        drop-off time must come from `drop_off.date_time` or
        `drop_off_date_time`. These rules are enforced at runtime but cannot be
        expressed in JSON Schema, so they do not appear in `required`.
      example:
        pick_up:
          airport_code: LYS
          date_time: '2026-09-12T10:00:00'
        drop_off_date_time: '2026-09-15T10:00:00'
        driver_age: 30
        residence_country: FR
        currency: EUR
    CarSearchResponse:
      type: object
      properties:
        offers:
          type: array
          items:
            $ref: '#/components/schemas/CarOffer'
        currency:
          type: string
          example: EUR
        resolved_place:
          $ref: '#/components/schemas/CarResolvedPlace'
        candidates:
          type: array
          items:
            $ref: '#/components/schemas/CarResolvedPlace'
          description: >-
            Returned instead of offers when a free-text `place` is ambiguous.
            Retry with `place` set to a candidate's `name`; when two candidates
            share a name, qualify it with the city — `"City Centre, Lyon"`.
        warnings:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
              message:
                type: string
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - AUTH_REQUIRED
                - PAYMENT_REQUIRED
                - RATE_LIMITED
                - BAD_REQUEST
                - FORBIDDEN
                - NOT_FOUND
                - CONFLICT
                - PRICE_CHANGED
                - QUOTE_EXPIRED
                - TRIP_EXPIRED
                - TRIP_STATE_CONFLICT
                - OFFER_EXPIRED
                - OFFER_UNAVAILABLE
                - MISSING_CUSTOMER_DETAILS
                - CURRENCY_UNSUPPORTED
                - UPSTREAM_REJECTED
                - UPSTREAM_UNAVAILABLE
                - UPSTREAM_TIMEOUT
                - UPSTREAM_ERROR
                - INTERNAL
              description: >-
                What went wrong, as a stable machine-readable code. This is a
                closed set — branch on it rather than on `message`, which is
                prose and may change. Codes are only ever ADDED, in a minor
                version, so treat an unknown one as its HTTP status.
              example: BAD_REQUEST
            message:
              type: string
            doc_url:
              type: string
          required:
            - code
            - message
      required:
        - error
    CarPickUp:
      type: object
      properties:
        date_time:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          description: Pick-up date-time, branch-local, no timezone.
          example: '2026-09-12T10:00:00'
        airport_code:
          type: string
          pattern: ^[A-Za-z]{3}$
          description: IATA airport code.
          example: LYS
        place:
          type: string
          minLength: 1
          description: >-
            Free-text location — a city, district or landmark. Resolved
            server-side; when the text is ambiguous the response carries
            `candidates` instead of offers — retry with a candidate's `name`.
          example: Lyon city centre
        geo:
          $ref: '#/components/schemas/CarGeo'
      required:
        - date_time
    CarDropOff:
      type: object
      properties:
        date_time:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          description: >-
            Drop-off date-time, branch-local. May instead be given as the
            top-level `drop_off_date_time`.
        airport_code:
          type: string
          pattern: ^[A-Za-z]{3}$
          description: IATA airport code.
          example: LYS
        place:
          type: string
          minLength: 1
          description: >-
            Free-text location — a city, district or landmark. Resolved
            server-side; when the text is ambiguous the response carries
            `candidates` instead of offers — retry with a candidate's `name`.
          example: Lyon city centre
        geo:
          $ref: '#/components/schemas/CarGeo'
      description: >-
        Where the car is returned. Omit for a round trip (return to the pick-up
        branch) and set `drop_off_date_time` instead.
    IntentInput:
      type: object
      properties:
        user_intent:
          type: string
          nullable: true
          description: >-
            The user's natural-language intent: the Alpic PII-stripped
            paraphrase when available, else a best-effort fallback to the
            client-provided NL query.
          example: find a cheap flight to Tokyo
    CarOffer:
      type: object
      properties:
        offer_id:
          type: string
          description: >-
            The trip item token. Pass verbatim to POST /v1/trip as
            trip_item_token to add this rental to a cart.
          example: car_9f3b2a17c4e8d501
        vehicle:
          $ref: '#/components/schemas/CarVehicle'
        package:
          $ref: '#/components/schemas/CarPackage'
        pick_up:
          $ref: '#/components/schemas/CarBranch'
        drop_off:
          $ref: '#/components/schemas/CarBranch'
        price:
          $ref: '#/components/schemas/CarOfferPrice'
        on_request:
          type: boolean
          description: >-
            The supplier confirms availability after booking rather than
            instantly.
        cancellation_fees:
          type: array
          items:
            $ref: '#/components/schemas/CarCancellationFee'
          description: >-
            Fee tiers by time before pick-up. An EMPTY list means the schedule
            is unknown — never render it as free cancellation.
        expires_at:
          type: string
          description: >-
            When the offer_id stops being addable to a trip. Re-search after
            this.
          example: '2026-09-12T10:30:00Z'
      required:
        - offer_id
    CarResolvedPlace:
      type: object
      properties:
        name:
          type: string
          example: Lyon City Centre
        kind:
          type: string
          description: >-
            One of "airport", "railway", "port" or "bus" — absent for a
            city-centre rental office.
          example: airport
        city:
          type: string
          example: Lyon
        country:
          type: string
          example: FR
      description: >-
        How a free-text `place` was interpreted. Echoed so the caller can
        confirm the resolution.
    CarGeo:
      type: object
      properties:
        latitude:
          type: number
          minimum: -90
          maximum: 90
          example: 45.7256
        longitude:
          type: number
          minimum: -180
          maximum: 180
          example: 5.0811
        range:
          type: integer
          minimum: 50
          description: Search radius around the coordinates (minimum 50).
          example: 5000
      required:
        - latitude
        - longitude
        - range
      description: >-
        Coordinates + radius. Searches the closest rental branches. Geo search
        is round-trip only: `drop_off` must be omitted or name the same place.
    CarVehicle:
      type: object
      properties:
        acriss_code:
          type: string
          example: CDMR
        name:
          type: string
          example: Honda Accord or similar
        category:
          type: string
          example: compact
        transmission:
          type: string
          example: manual
        fuel_type:
          type: string
        seats:
          type: string
          description: A string — suppliers publish ranges like "5-7".
          example: '5'
        doors:
          type: string
          description: A string, like seats.
        air_conditioned:
          type: boolean
    CarPackage:
      type: object
      properties:
        name:
          type: string
          example: Fully Inclusive
        supplier_name:
          type: string
          example: Avis
        supplier_code:
          type: string
        fuel_policy:
          type: string
          example: full_to_full
        mileage_unlimited:
          type: boolean
        mileage_allowance:
          type: string
        inclusions:
          type: array
          items:
            nullable: true
        coverages:
          type: array
          items:
            nullable: true
        fees:
          type: array
          items:
            nullable: true
    CarBranch:
      type: object
      properties:
        name:
          type: string
          example: Lyon Saint-Exupery Airport
        address:
          type: string
        city:
          type: string
          example: Lyon
        country:
          type: string
          example: FR
        date_time:
          type: string
          description: The pick-up or drop-off time at this branch, branch-local.
          example: '2026-09-12T10:00:00'
        time_zone:
          type: string
          example: Europe/Paris
        latitude:
          type: number
        longitude:
          type: number
    CarOfferPrice:
      type: object
      properties:
        pay_now:
          $ref: '#/components/schemas/CarAmount'
        due_at_desk:
          allOf:
            - $ref: '#/components/schemas/CarAmount'
            - description: >-
                Collected by the rental desk locally, in local currency.
                Display-only.
        estimated_total:
          allOf:
            - $ref: '#/components/schemas/CarAmount'
            - description: pay_now + due_at_desk, where both are known.
        deposit:
          allOf:
            - $ref: '#/components/schemas/CarAmount'
            - description: Security hold taken at the desk, not a charge.
    CarCancellationFee:
      type: object
      properties:
        type:
          type: string
          example: cancellation
        fee:
          $ref: '#/components/schemas/CarAmount'
        non_refundable:
          type: boolean
        applicable_from:
          type: string
        applicable_to:
          type: string
        applicable_now:
          type: boolean
        seconds_before_pick_up:
          type: number
    CarAmount:
      type: object
      properties:
        value:
          type: integer
          description: >-
            Integer amount in MINOR units, always paired with decimal_places —
            divide by 10 ** decimal_places to display. Example: value 15977 with
            decimal_places 2 is 159.77 USD. Rendering this field directly shows
            prices 100x too high for 2-decimal currencies.
          example: 41250
        currency:
          type: string
          description: ISO 4217 currency code.
          example: EUR
        decimal_places:
          type: integer
          description: >-
            Scale of the integer value/amount: display = integer / 10 **
            decimal_places. Always sent alongside minor-unit amounts. Usually
            the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for
            JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry
            a different scale — ALWAYS use the decimal_places sent with the
            amount, never a hardcoded 2. Only if the field is genuinely absent
            on a value-shaped object, fall back to the ISO digits for the
            currency.
          example: 2
      description: The only amount Jinko charges at checkout.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BearerAuth:
      type: http
      scheme: bearer

````