openapi: 3.0.0
info:
  description: Cabify Delivery API
  version: 1.0.0
  title: Delivery API
  contact:
    email: p.delivery@cabify.com
tags:
  - name: parcels
    description: It's the package you need to send. It's a unit, identified by an unique
      code, which includes a pick-up and a drop-off (destination) point.
  - name: delivery
    description: Use this endpoint to set the parcels as ready to send. Be
      ready, a driver will appear soon to fetch them!
  - name: status
    description: Track the status and the position of your parcels in every moment.
  - name: webhooks
    description: Subscribe to parcel updates to get live information about the status.
paths:
  /parcels:
    post:
      tags:
        - parcels
      summary: Add new parcels to the system.
      description: Create the parcels you need to deliver. Please note that they won't be
        delivered until you call the /parcels/deliver endpoint.
      operationId: addParcels
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewParcels"
        description: List of parcels you want to create.
        required: true
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Parcels"
        400:
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestError"
        401:
          description: Unauthorized
        422:
          description: Unprocessable entity
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestError"
      security:
        - bearer_token: []
    get:
      tags:
        - parcels
      summary: Search parcels filtering by different fields.
      description: Returns a paginated list of parcels
      operationId: getParcels
      parameters:
        - name: state
          in: query
          description: State of parcels to return
          required: true
          schema:
            type: string
            enum:
              - ready
              - qualifiedforpickup
              - onroutetopickup
              - pickingup
              - intransit
              - delivering
              - delivered
              - returning
              - returned
              - incident
              - requestercanceled
              - internalcanceled
              - pickupfailed
        - name: page
          in: query
          description: Page to return. If you don't send the page number, the first one will be returned.
          required: false
          schema:
              type: number
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaginatedParcels"
        401:
          description: Unauthorized
      security:
        - bearer_token: []
  /parcels/{parcel_id}:
    get:
      tags:
        - parcels
      summary: Get parcel by ID
      description: Fetch the parcel with the given ID
      operationId: getParcel
      parameters:
        - in: path
          name: parcel_id
          description: Id of the parcel
          required: true
          schema:
            type: string
            format: uuid
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Parcel"
        401:
          description: Unauthorized
        404:
          description: Not Found
      security:
        - bearer_token: []
    delete:
      tags:
        - parcels
      summary: Delete parcel by ID
      description: Delete the parcel with the given ID. Only unsent parcels can be deleted.
      operationId: deleteParcel
      parameters:
        - in: path
          name: parcel_id
          description: Id of the parcel
          required: true
          schema:
            type: string
            format: uuid
      responses:
        200:
          description: Success
        401:
          description: Unauthorized
        404:
          description: Not Found
      security:
        - bearer_token: []
  /parcels/estimate:
    post:
      tags:
        - parcels
      summary: Estimates the Delivery
      description: Returns the estimated cost of the delivery of the given parcels and estimated time for pick up and delivery
      operationId: estimateParcels
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EstimateParcels"
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EstimationResponse"
        400:
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestError"
        401:
          description: Unauthorized
        422:
          description: Unprocessable entity
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestError"
      security:
        - bearer_token: []
  /parcels/deliver:
    post:
      tags:
        - delivery
      summary: Deliver the given parcels.
      description: Set the given parcels as ready to deliver. It's a batch operation, it will fail in one of the given parcels is not found.
      operationId: deliverParcels
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DeliverParcels"
      responses:
        202:
          description: Accepted
        401:
          description: Unauthorized
      security:
        - bearer_token: []
  /parcels/deliver/cancel:
    post:
      tags:
        - delivery
      summary: Cancel the delivery of the given parcels.
      description: Cancels the delivery, when it's possible. For instance, it can't be cancelled if it has been picked up.
        States allowed to cancel are qualifiedforpickup and pickingup.
        Please note that this operation may incur costs.
      operationId: cancelParcels
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CancelParcels"
      responses:
        202:
          description: Success
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict. The delivery can't be cancelled due the current state. It can be cancelled if state is qualifiedforpickup or pickingup, right after /v1/parcels/deliver call.
      security:
        - bearer_token: []
  /parcels/{parcel_id}/status:
    get:
      tags:
        - status
      summary: Status of the given parcel
      description: Return the status of the given parcel.
      operationId: statusParcel
      parameters:
        - in: path
          name: parcel_id
          description: ID of the parcel to track
          required: true
          schema:
            type: string
            format: uuid
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParcelStatus"
        401:
          description: Unauthorized
        404:
          description: Not Found
      security:
        - bearer_token: []
  /webhooks:
    post:
      tags:
        - webhooks
      summary: Subscribe to the parcels updates
      description: Use this webhooks to receive live information of the parcels updates.
      operationId: subscribeWebhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookSubscription"
        description: Webhooks you want to subscribe
        required: true
      responses:
        201:
            description: Success
        400:
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestError"
        401:
          description: Unauthorized
      security:
        - bearer_token: []
      callbacks:
        parcel:
          '{$request.body#/callback_url}':
            post:
              parameters:
                - in: header
                  name: '{$request.body#/headers/name}'
                  schema:
                    type: string
                - in: header
                  name: '{$request.body#/headers/value}'
                  schema:
                    type: string
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/ParcelStatus"
              responses:
                200:
                  description: Success
    get:
      tags:
        - webhooks
      summary: Fetch your current webhooks subscriptions
      description: ""
      operationId: getWebhook
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ResponseWebhookSubscriptions"
        401:
          description: Unauthorized
      security:
        - bearer_token: []
  /webhooks/{hook}:
    delete:
      tags:
        - webhooks
      summary: Delete your webhook subscriptions
      description: ""
      operationId: deleteWebhook
      parameters:
        - in: path
          name: hook
          description: Webhook to unsubscribe
          required: true
          schema:
            type: string
            enum:
              - parcel
      responses:
        200:
          description: Success
        401:
          description: Unauthorized
      security:
        - bearer_token: []
externalDocs:
  description: Find out more about Cabify API
  url: https://developers.cabify.com
servers:
  - url: https://delivery.api.cabify-sandbox.com/v1
components:
  securitySchemes:
    bearer_token:
      type: http
      scheme: bearer
  schemas:
    NewParcels:
      type: object
      required:
        - parcels
      properties:
        parcels:
          type: array
          items:
            $ref: "#/components/schemas/NewParcel"
    NewParcel:
      type: object
      required:
        - pickup_addr
        - dropoff_addr
        - dropoff_contact_name
      properties:
        external_id:
          type: string
          description: Use this property to store your own parcel ID.
          example: parcel_001
        pickup_info:
          $ref: "#/components/schemas/ParcelPointPickupInfo"
        dropoff_info:
          $ref: "#/components/schemas/ParcelPointDropoffInfo"
        dimensions:
          $ref: "#/components/schemas/ParcelDimensions"
        weight:
          $ref: "#/components/schemas/ParcelWeight"
    ParcelPointPickupInfo:
      type: object
      required:
        - addr
        - contact
      properties:
        addr:
          type: string
          description: The full address where the parcel should be picked up.
          example: Calle de Pradillo, 42, Madrid
        contact:
          $ref: "#/components/schemas/NewParcelPickupContact"
        instr:
          type: string
          nullable: true
          description: This instructions will be given to the driver during the pick-up.
          example: Knock the door three times
        loc:
          $ref: "#/components/schemas/Point"
    ParcelPointDropoffInfo:
      type: object
      required:
        - addr
        - contact
      properties:
        addr:
          type: string
          description: The full address where the parcel should be picked up.
          example: Calle de Pradillo, 42, Madrid
        contact:
          $ref: "#/components/schemas/NewParcelDropoffContact"
        instr:
          type: string
          nullable: true
          description: This instructions will be given to the driver during the pick-up.
          example: Knock the door three times
        loc:
          $ref: "#/components/schemas/Point"
    ParcelDimensions:
      type: object
      properties:
        height:
          type: integer
          minimum: 0
          example: 10
        length:
          type: integer
          minimum: 0
          example: 10
        width:
          type: integer
          minimum: 0
          example: 10
        unit:
          type: string
          description: Indicate the unit of measure for the provided dimensions. Any value other than the allowed ones, including blank/null, will default to cm.
          enum:
            - cm
    ParcelWeight:
      type: object
      properties:
        value:
          type: number
          format: float
          minimum: 0
          example: 1500
        unit:
          type: string
          description: Indicate the unit of weight. Any value other than the allowed ones, including blank/null, will default to g (grams).
          enum:
            - g
    NewParcelPickupContact:
      type: object
      properties:
        name:
          type: string
          nullable: true
          description: The contact name of the person at the pick-up location.
          example: Jhon
        phone:
          type: string
          nullable: true
          description: The contact phone of the person at the pick-up location.
          example: "+34666000000"
    NewParcelDropoffContact:
      type: object
      properties:
        name:
          type: string
          description: The contact name of the person at the pick-up location.
          example: Jhon
        phone:
          type: string
          nullable: true
          description: The contact phone of the person at the pick-up location.
          example: "+34666000000"
    Parcel:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Parcel ID
          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
        external_id:
          type: string
          description: Use this property to store your own parcel ID.
          example: parcel_001
        pickup_info:
          $ref: "#/components/schemas/ParcelPointPickupInfo"
        dropoff_info:
          $ref: "#/components/schemas/ParcelPointDropoffInfo"
        dimensions:
          $ref: "#/components/schemas/ParcelDimensions"
        weight:
          $ref: "#/components/schemas/ParcelWeight"
        created_at:
          type: string
          format: date-time
          description: Date and time when the package has been created in the system.
          example: "2021-12-02T10:12:07.753Z"
        updated_at:
          type: string
          format: date-time
          description: Date and time when the package has been last modified.
          example: "2021-12-02T10:12:07.753Z"
    Point:
      type: object
      required:
        - lat
        - lon
      properties:
        lat:
          type: number
          format: float
          example: "40.4489254"
        lon:
          type: number
          format: float
          example: "-3.6730293"
    ParcelStatus:
      type: object
      properties:
        id:
          type: string
          format: uuid
        state:
          type: string
          enum:
            - ready
            - qualifiedforpickup
            - pickingup
            - intransit
            - delivering
            - delivered
            - returning
            - returned
            - incident
            - requestercancel
            - internalcancel
            - pickupfailed
            - onroutetopickup
        delivery_attempt:
          type: object
          properties:
            proof_of_delivery:
              type: object
              nullable: true
              properties:
                recipient_name:
                  type: string
                  description: The name of the person who has received the parcel.
                  example: "Francisco"
                recipient_id_number:
                  type: string
                  example: "11111111T"
                  description: The ID of the person who has received the parcel.
                photo_url:
                  type: string
                  example: "https://s3.amazon.com/photo.jpg"
                  description: URL of the photo taken by the driver in the case you have this kind of proof of delivery configured.
                types:
                  type: array
                  description: Types of proof of delivery configured during the delivery of this parcel.
                  items:
                    type: string
                    enum:
                      - id
                      - photo
            fail_reason:
              type: string
              enum:
                - recipient_not_found
                - rejected
                - wrong_address
                - zone_unsafe
                - other
            support_ticket:
              type: string
              nullable: true
              description: ID of the suport ticket opened by the driver in the case an incident happens.
        tracking:
          type: object
          nullable: true
          properties:
            eta_to_accept:
              type: integer
              nullable: true
              example: 90
            location:
              type: object
              nullable: true
              properties:
                lat:
                  type: number
                  example: 1.1234
                lon:
                  type: number
                  example: 1.1234
            routes:
              type: object
              properties:
                pick_up:
                  $ref: "#/components/schemas/ParcelStatusRoute"
                drop_off:
                  $ref: "#/components/schemas/ParcelStatusRoute"
            tracking_url:
              type: string
        asset:
          type: object
          properties:
            reg_plate:
              type: string
              nullable: true
              example: "1111AAA"
            name:
              type: string
              example: "Audi A3"
            color:
              type: string
              example: "black"
        driver:
          type: object
          nullable: true
          properties:
            photo_url:
              type: string
              example: "https://s3.amazon.com/photo.jpg"
            name:
              type: string
              example: "Pepe"
            phone:
              type: string
              description: The contact phone of the driver
              example: "+34658478854"
    ParcelStatusRoute:
      type: object
      required:
        - eta
        - path
      properties:
        eta:
          type: integer
          example: 120
        path:
          type: string
          example: "fhdsa98fha87sdfhas76dgf8a"
    DeliverParcels:
      type: object
      required:
        - parcel_ids
      properties:
        parcel_ids:
          type: array
          description: List of parcels to deliver
          items:
            type: string
            format: uuid
        optimize:
          type: boolean
          description: Set to false if you want to deliver the parcels following the given order instead of search the sorter route.
          default: true
        requester_id:
          type: string
          format: uuid
          description: Identifier of user that request the delivery
    CancelParcels:
      type: object
      required:
        - parcel_ids
      properties:
        parcel_ids:
          type: array
          description: List of parcels to be cancelled
          items:
            type: string
            format: uuid
    EstimateParcels:
      type: object
      required:
        - parcel_ids
      properties:
        parcel_ids:
          type: array
          description: List of parcels to make an estimation.
          items:
            type: string
            format: uuid
    PaginatedParcels:
      type: object
      required:
        - parcels
        - page
        - page_size
        - more_pages
      properties:
        parcels:
          type: array
          items:
            $ref: "#/components/schemas/Parcel"
        page:
          type: number
          description: Number of the page returned
          example: 2
        page_size:
          type: number
          description: Size of the page
          example: 20
        more_pages:
          type: boolean
          description: True if there are more elements with this criteria
          example: true
    Parcels:
      type: object
      required:
        - parcels
      properties:
        parcels:
          type: array
          items:
            $ref: "#/components/schemas/Parcel"
    ParcelsStatus:
      type: object
      required:
        - parcels
      properties:
        parcels:
          type: array
          items:
            $ref: "#/components/schemas/ParcelStatus"
    EstimationResponse:
      type: object
      required:
        - price
        - eta_to_pickup
      properties:
        price:
          $ref: "#/components/schemas/Money"
        eta_to_pickup:
          type: integer
          description: Estimated seconds from the request to a driver in the pick up point
          example: 180
        eta_to_delivery:
          type: integer
          description: Estimated seconds from pick up point to the last delivery point if there is more than one or just one.
          example: 180
    Money:
      type: object
      required:
        - amount
        - currency
      properties:
        amount:
          description: "Cost in minor units (ex: 6'30€ -> 630)"
          type: integer
          example: 630
        currency:
          type: string
          example: EUR
    ResponseWebhookSubscriptions:
      type: object
      required:
        - subscriptions
      properties:
        subscriptions:
          type: array
          items:
            $ref: "#/components/schemas/ResponseWebhookSubscription"
    ResponseWebhookSubscription:
      type: object
      required:
        - id
        - callback_url
        - hook
      properties:
        id:
          type: number
        hook:
          type: string
          enum:
            - parcel
          description: You can subscribe to get live information of every parcel individually.
        callback_url:
          type: string
          format: uri
          example: http://example.com/your/callback/here
          description: This is your URL. This API will do a POST request every time the parcel is updated.
        headers:
          type: array
          items:
            $ref: "#/components/schemas/Header"
          description: If your endpoint needs extra headers to accept the request (for instance, authentication) you can add them here.
    WebhookSubscription:
      type: object
      required:
        - callback_url
        - hook
      properties:
        hook:
          type: string
          enum:
            - parcel
          description: You can subscribe to get live information of every parcel individually.
        callback_url:
          type: string
          format: uri
          example: http://example.com/your/callback/here
          description: This is your URL. This API will do a POST request every time the parcel is updated.
        headers:
          type: array
          items:
            $ref: "#/components/schemas/Header"
          description: If your endpoint needs extra headers to accept the request (for instance, authentication) you can add them here.
    Header:
      type: object
      required:
        - name
        - value
      properties:
        name:
          type: string
          description: Header name
          example: Authorization
        value:
          type: string
          description: Header value
          example: Bearer 000111222333444
    RequestError:
      type: object
      required:
        - errors
      properties:
        errors:
          type: array
          items:
            type: string
