Cabify Ride-Hailing API

REST API (v4) to estimate prices, book and cancel journeys, track journey state in real time, manage riders and labels, look up venue hubs and meeting points, and retrieve sales. Legacy v3 GraphQL remains available at /api/v3/graphql for existing integrations. OAuth2 client-credentials Bearer authentication; asynchronous journey-state updates via webhooks.

OpenAPI Specification

cabify-ride-hailing-openapi.yml Raw ↑
info:
  contact:
    email: ridehailing.api@cabify.support
  license:
    name: Cabify Api support
    url: https://cabify.com
  title: Cabify Ride-Hailing API
  version: '4.0'
openapi: 3.0.0
security:
- access_token: []
servers:
- url: https://cabify.com
  description: Production
- url: https://cabify-sandbox.com
  description: Sandbox
tags:
- description: This section covers the mobility solution for all companies looking to transport their
    employees in a simple, safe and comfortable way. We offer different types of vehicles with private
    drivers and provide everything you need to enjoy your journey, such as a good driver and a top-of-the-range
    car.
  name: Journeys
- description: Cabify offers to its clients a feature where the client’s employees have to input a journey
    motive or a project or a dynamic cost center associated with the new journey before requesting it.
    This is usually used for financial budgeting and reporting purposes since every journey now comes
    with this data linked to it, in other words, clients can segment their invoices by these Labels. <br>
    <br> Since some companies have a lot of Labels (projects/cost centers) that need to be managed they
    can use our API to do so. We allow creating, modifying, and disabling them directly from, for example,
    the client’s ERP (SAP, NetSuite, MSDynamics, etc.).
  name: Labels
- description: This method returns prices, Id's and all the information for products that are available
    at the origin point. Before requesting a journey as a first step it is necessary to obtain the different
    products configured in your account in order to select the one that fits your needs and keep the Id
    that will be used in the Journey.
  name: Estimates
- description: "Sales objects are created once a journey transitions into the terminated state and they\
    \ are associated with the user who requested the journey (which not necessarily is the rider).\n \
    \           <br> <br>The transition to terminated happens automatically after 2 hours in production\
    \ (10 minutes in sandbox environment).\n            <br> <br>You can request them per user (requester\
    \ of the journey), the client (all of your sales), or journey (all Sales associated to a specific\
    \ journey which in most cases is just one)."
  name: Sales
paths:
  /api/v4/journey/{id}/state:
    post:
      callbacks: {}
      description: 'Cancels an active journey. Journeys can only be cancelled free of charge before a
        driver has been assigned. After assignment, cancellation fees may apply if the courtesy period
        has elapsed (this varies by operating zone).


        Returns `409 Conflict` if the journey has already been completed, terminated, or is in a state
        that does not allow cancellation.

        '
      operationId: cancelJourney
      parameters:
      - description: Id of the journey
        example: f0397896-19aa-11ed-b6fe-7aaea8067492
        in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conflict'
          description: Journey cannot be cancelled (already terminated or in a non-cancellable state)
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Cancel Journey
      tags:
      - Journeys
    get:
      callbacks: {}
      description: 'Returns the real-time operational state of an active journey: assigned driver, vehicle,
        and

        the route waypoints collected so far.


        Use this endpoint for live tracking while a journey is in progress. It provides the data

        needed to show the driver''s position on a map and display vehicle/driver details to the rider.


        **Typical use cases:**

        - Show the assigned driver''s name, phone number, and avatar.

        - Display the vehicle plate, model, and color so the rider can identify it.

        - Plot the driver''s route on a map using the waypoints array.


        **Availability:**

        - Returns data once a driver is assigned (`hired` state onward).

        - Returns empty waypoints for journeys in `terminated` state (route data is archived).

        - Returns `404` if the journey does not exist or does not belong to the authenticated client.


        > ⚠️ Stop polling once you receive an end state

        >

        > End states are terminal, the journey will never transition to another state. Once you receive
        an

        > end state (via this endpoint or a webhook), stop polling. Continued polling returns `200` with

        > `state: terminated` indefinitely but carries no new information.

        >

        > For reliable state delivery without polling, configure

        > [Journey State Updates webhooks](https://developers.cabify.com/docs/journey-updates-webhook).


        > 📘 Looking for booking details or pricing?

        >

        > To retrieve stops, cost breakdown, or lifecycle status, use the

        > [Get Journey Details](#operation/getJourney) endpoint instead.

        >

        > To receive state changes in real time without polling, configure

        > [Webhooks](https://developers.cabify.com/docs/journey-updates-webhook).

        '
      operationId: getJourneyState
      parameters:
      - description: UUID of the journey
        example: f0397896-19aa-11ed-b6fe-7aaea8067492
        in: path
        name: id
        required: true
        schema:
          type: string
      - description: ID of the user who requested the journey
        example: 6f80363aa84fa61a58dc5720
        in: query
        name: requester_id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyState'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
          description: Not found
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get Journey State
      tags:
      - Journeys
  /api/v4/journey:
    post:
      callbacks: {}
      description: 'Creates a new journey request for a ride.


        > ❗️ Prerequisites

        >

        > Before creating a journey, you **must** call the `/estimates` endpoint and use the returned

        > `product.id` as `product_id` in this request. This guarantees that the product is available

        > at the pickup location and provides accurate pricing shown to drivers.

        >

        > The estimate should be created within **5 minutes** of the journey request.


        ## Journey States


        After creation, the journey progresses through these states:

        1. `hire` - Searching for available drivers

        2. `hired` - Driver assigned and en route

        3. `arrived` - Driver at pickup location

        4. `pick up` - Passenger in vehicle

        5. `drop off` - Journey completed

        6. `terminated` - Receipt generated (after ~2 hours)

        For a detailed explanation of journey states and their transitions, see [Journey States](https://developers.cabify.com/docs/journey-states).


        > 📘 Booking a Journey (Reservation)

        >

        > Creating a reservation is similar to creating an ASAP journey, except for the `start_at` field,

        > which should contain a future date-time value in the format "YYYY-MM-DD HH:MM:SS", expressed

        > in the local time of the pickup location.

        >

        > **Use the same `start_at` value you provided to the `/estimates` endpoint** to ensure consistent

        > product availability and pricing between the estimate and the journey creation.

        >

        > **Important constraints:**

        > - Reservations must be created at least **30 minutes** before the start time

        > - Reservations can be scheduled up to **60 days** in advance


        > ⚠️ Sandbox Testing

        >

        > In the sandbox environment, pickup locations must be within central Madrid (approximately 40.4361°,
        -3.7014°).

        > See [Sandbox Environment](https://developers.cabify.com/docs/sandbox-environment) for details.

        '
      operationId: createJourney
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JourneyRequest'
        description: Journey request
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
          description: Not found
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Create a journey
      tags:
      - Journeys
  /api/v4/labels:
    post:
      callbacks: {}
      description: Creates a new label.
      operationId: createLabel
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LabelRequest'
        description: The Label attributes
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LabelResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Create a Label
      tags:
      - Labels
    get:
      callbacks: {}
      description: Fetch labels paginated
      operationId: getLabels
      parameters:
      - description: Amount of labels for page
        example: 20
        in: query
        name: per
        schema:
          default: 20
          type: integer
      - description: Number of page to fetch
        example: 1
        in: query
        name: page
        schema:
          default: 1
          type: integer
      - description: Filter by active Labels. If not set then all Labels are returned
        example: true
        in: query
        name: active
        schema:
          type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedLabelResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get labels paginated
      tags:
      - Labels
    patch:
      callbacks: {}
      description: Modify an existing label
      operationId: updateLabel
      parameters:
      - description: Id of the label
        example: 93aba78c-8876-4a75-ae4d-3d4e31ab8334
        in: query
        name: id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LabelUpdateRequest'
        description: The Label attributes
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LabelResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Update label
      tags:
      - Labels
  /api/v4/users:
    post:
      callbacks: {}
      description: Create Users in bulk
      operationId: createUsers
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUsersRequest'
        description: Create Users Request
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MutationResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Create Users in bulk
      tags:
      - Users
    get:
      callbacks: {}
      description: Gets multiple Users
      operationId: getUsers
      parameters:
      - description: id of the User, UUIDv4 format without hyphens
        example: active
        in: query
        name: state
        schema:
          default: active
          enum:
          - active
          - pending
          - disabled
          type: string
      - description: Number of page to return
        example: 1
        in: query
        name: page
        schema:
          default: 1
          type: number
      - description: Number of elements per page
        example: 20
        in: query
        name: per
        schema:
          default: 20
          type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get Users in bulk
      tags:
      - Users
    patch:
      callbacks: {}
      description: Update Users in bulk
      operationId: updateUsers
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateUsersRequest'
        description: UpdateUsersRequest
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MutationResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Update Users in bulk
      tags:
      - Users
  /api/v4/estimates:
    post:
      callbacks: {}
      description: 'Obtain prices, product IDs, and all the information for products that are available
        at the origin point.


        > ❗️ Important

        >

        > You **must** call this endpoint before creating a Journey. The response provides the `product.id`

        > that should be passed to the journey creation endpoint.

        >

        > For **reserved** journeys, pass the same `start_at` used here to the journey creation request

        > to guarantee consistent product availability and pricing.

        >

        > We recommend estimating no more than **5 minutes** before creating the journey.


        ## Response


        The response contains an array of available products, each with:

        - `product.id` — pass as `product_id` when creating a journey

        - Estimated price and currency

        - ETA (estimated time of arrival)

        - Vehicle category information


        ## Hub Information


        When the origin is within a large venue (airport, train station, etc.), each estimation object
        may include a `hub` field containing:

        - Hub metadata (uid, title, location_id)

        - A list of **meeting points** — designated pick-up locations with coordinates, images, and localized
        instructions


        The `hub` field is resolved on a best-effort basis in parallel with pricing. It may be `null`
        if hub resolution does not complete in time or no hub exists at the origin.


        > 📘 Using Hub Data

        >

        > When a hub is present, present the meeting points to the user for selection and include the
        chosen one in the journey creation request via the `meeting_point` field in the origin stop.

        > Alternatively, use `GET /api/v4/hub` to look up hub data independently.

        '
      operationId: getEstimation
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EstimateRequest'
        description: Estimate request
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EstimateResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Create estimation
      tags:
      - Estimates
  /api/v4/hub:
    get:
      callbacks: {}
      description: 'Look up hub meeting-point data for a given set of coordinates.


        A **hub** is a large venue (e.g. airport, train station) with designated pick-up/drop-off meeting
        points. Use this endpoint to determine if a location is within a hub and retrieve the available
        meeting points.


        ## Response


        - If a hub exists at the given coordinates, returns the hub with its meeting points (uid, title,
        coordinates, images, and localized instructions).

        - If no hub exists or the lookup fails, returns `{ "data": null }`.


        ## Usage


        This endpoint is useful when you want to look up hub data independently from the estimation flow.
        For example:

        1. User enters a pickup address

        2. Call this endpoint with the address coordinates

        3. If a hub is returned, present the meeting points to the user

        4. Include the selected meeting point **and** the hub''s `location_id` in the corresponding stop
        of the `POST /api/v4/journey` request


        > 📘 Hub data in Estimates

        >

        > Hub data is also returned as part of the `POST /api/v4/estimates` response (best-effort, origin
        stop only).

        > Use this standalone endpoint when you need hub data without creating an estimate, or when the
        estimate did not resolve hub data in time.

        '
      operationId: getHub
      parameters:
      - description: Latitude of the location to look up.
        in: query
        name: latitude
        required: true
        schema:
          type: number
      - description: Longitude of the location to look up.
        in: query
        name: longitude
        required: true
        schema:
          type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
      summary: Get Hub by coordinates
      tags:
      - Hubs
  /api/v4/journey/{journey_id}:
    get:
      callbacks: {}
      description: 'Returns the booking-level details of a journey: stops, pricing, timestamps, and lifecycle
        status.


        Use this endpoint to check whether a journey is finished, retrieve its cost breakdown, or read

        the stops that were requested. The response is stable once the journey is created and only

        changes when the journey ends (populating `end_state`, `end_at`, and `totals`).


        **Typical use cases:**

        - Display a journey''s origin/destination and scheduled time.

        - Check if a journey has finished and why (`end_state`).

        - Retrieve the price summary after a journey is terminated.


        > 📘 Looking for real-time tracking data?

        >

        > To get the driver''s current location, vehicle details, or route waypoints while a journey is

        > in progress, use the [Get Journey State](#operation/getJourneyState) endpoint instead.

        '
      operationId: getJourney
      parameters:
      - description: UUID of the journey
        example: f0397896-19aa-11ed-b6fe-7aaea8067492
        in: path
        name: journey_id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Journey'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get Journey details
      tags:
      - Journeys
  /api/v4/journey/{journey_id}/sales:
    get:
      callbacks: {}
      description: Fetch the sales of the journey
      operationId: getJourneySales
      parameters:
      - description: Id of the journey
        example: 6f80363aa84fa61a58dc5720
        in: path
        name: journey_id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Sale'
                type: array
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
          description: Not found
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get journey's sales
      tags:
      - Sales
  /api/v4/labels/{id}:
    get:
      callbacks: {}
      description: Fetch the label with the given Id
      operationId: getLabelById
      parameters:
      - description: Id of the label
        example: 93aba78c-8876-4a75-ae4d-3d4e31ab8334
        in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LabelResponse'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
          description: Not found
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get label by Id
      tags:
      - Labels
  /api/v4/sales:
    get:
      callbacks: {}
      description: Get sales paginated
      operationId: getSales
      parameters:
      - description: Start date
        example: '2021-12-01'
        in: query
        name: from
        required: true
        schema:
          format: date
          pattern: '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])'
          type: string
      - description: End date
        example: '2021-12-01'
        in: query
        name: to
        required: true
        schema:
          format: date
          pattern: '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])'
          type: string
      - description: Currency of the sale
        example: EUR
        in: query
        name: currency
        required: true
        schema:
          default: EUR
          enum:
          - EUR
          - CLP
          - PEN
          - MXN
          - COP
          - USD
          - BRL
          - ARS
          type: string
      - description: Number of page to fetch
        example: 1
        in: query
        name: page
        required: true
        schema:
          default: 1
          type: integer
      - description: Amount of sales per page
        example: 20
        in: query
        name: per
        required: true
        schema:
          default: 20
          type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Expense'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '500':
          content:
            application/text:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Fetch client's sales paginated
      tags:
      - Sales
  /api/v4/users/email/{email}:
    get:
      callbacks: {}
      description: Gets a User by email
      operationId: getUserByEmail
      parameters:
      - description: Email of the User to search
        example: john.doe@example.com
        in: path
        name: email
        required: true
        schema:
          format: email
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest'
          description: Bad request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedRequest'
          description: Unauthorized
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFound'
          description: Not found
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerError'
          description: Internal server error
      summary: Get User by email
      tags:
      - Users
  /api/v4/users/{id}:
    get:
      callbacks: {}
      description: Get User by id
      operationId: getUserById
      parameters:
      - description: ID of the User to search
        example: 01234567890123456789012345678901
        in: path
        name: id
        required: true
        schema:
          pattern: ^[a-f0-9]{32}$
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
  

# --- truncated at 32 KB (92 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/cabify/refs/heads/main/openapi/cabify-ride-hailing-openapi.yml