FRAYT Client API

REST API (v2.2) for FRAYT's on-demand and scheduled delivery marketplace. Price a delivery with the match-estimate endpoints, authorize an estimate into a Match, retrieve and update a Match, update a stop to add a driver tip, and cancel a Match. OAuth 2.0 client-credentials issues the bearer token every other call requires. Webhook callbacks (match_update) are declared inline in the OpenAPI so subscribers receive the full Match payload on every state transition.

Documentation

Specifications

Other Resources

OpenAPI Specification

frayt-matches-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: FRAYT API — Matches
  version: '2.2'
  description: "<h2>Introduction</h2>\n<p>Welcome to the FRAYT's REST API.  Each endpoint is documented individually, and\
    \ the endpoints are categorized by the resource that they primarily affect (Matches, and OAuth). By following the outlined\
    \ schema of each endpoint, our API allows you to integrate FRAYT's logistics services seamlessly into your application.</p>\n\
    \n<h3>FRAYT Terminology</h3>\n  <p>The logistics industry tends to have a wide variety of terms for a single item. So\
    \ let's make sure we define our terms before getting into the API:</p>\n    <ul>\n      <li><b>Match:</b> this is an individual\
    \ order placed in the FRAYT system for a driver to deliver</li>\n      <li><b>Estimate:</b> this provides a dollar amount\
    \ in the response prior to it becoming a match. Estimates can be authorized into matches by passing the same payload but\
    \ to the matches endpoint</li>\n    </ul>\n\n<h3>FRAYT Workflows</h3>\n  <p>Now that we have our terms defined, let's\
    \ paint a bigger picture of what the life of a match looks like. These examples are the most common but are by no means\
    \ exhaustive.</p>\n    <ul>\n      <li><b>Golden Path:</b> Pending (estimate)->Assigning Driver (live match to whole marketplace)->Accepted\
    \ (by a driver)->En Route to Pickup->Arrived at Pickup->Picked Up<b><font color=\"red\">*</font></b>->Completed (delivered)->Charged</li>\n\
    \      <li><b>Unable to Pickup:</b> Pending->Assigning Driver->Accepted>En Route to Pickup->Arrived at Pickup->Unable\
    \ to Pickup</li>\n      <li><b>Unable to Dropoff:</b> Pending->Assigning Driver->Accepted->En Route to Pickup->Arrived\
    \ at Pickup->Picked Up<b><font color=\"red\">*</font></b>->En Route to Return->Arrived at Return->Charged</li>\n     \
    \ <li><b>Preferred Driver:</b> Pending->Offered (only to preferred driver, not marketplace)->Accepted->En Route to Pickup->Arrived\
    \ at Pickup->Picked Up<b><font color=\"red\">*</font></b>->Completed->Charged</li>\n      <p><i><b><font color=\"red\"\
    >*</font></b>Once a match is picked up, the match.stop state changes from Pending–>En Route–>Arrived–>Signed–>Delivered\
    \ or Returned</i></p>\n    </ul>\n\n<h2> Endpoints and Requests</h2>\n<p>The FRAYT API endpoints are organized as <b>matches,\
    \ match estimates, and oauth</b>. Once authentication has been made, the primary endpoint used will be the Matches endpoint\
    \ for all estimates and matches.\n\nOur endpoints have a base url of https://api.frayt.com/api/v2.2/\n\nThe <b>schema</b>\
    \ for each endpoint lists the properties <i>and provides a brief description to provide context for your mapping needs</i>.\
    \ Additionally, <b>all required properties</b> are listed with a <font color=\"red\">red asterisk</font> (<font color=\"\
    red\">*</font>).</p>\n\n\n  <h3> Authentication </h3>\n    <p>All FRAYT API requests require a valid bearer token. To\
    \ generate your bearer token, you will need to hit the <a href=\"/docs/api/v2.2/#/oauth/FraytElixirWeb.API.OauthController.authenticate\"\
    \ target=\"oauth\">OAuth endpoint</a> passing your Client ID and Secret in the payload.\n    To acquire your Client ID\
    \ and Secret, reach out to the FRAYT team at <a href=\"mailto:dev@frayt.com\">dev@frayt.com</a>.</p>\n\n  <h3>Match Estimates\
    \ </h3>\n    <p>The <a href=\"/docs/api/v2.2/#/match%20estimates/FraytElixirWeb.API.V2x2.MatchEstimateController.create\"\
    \ target=\"match estimates\">match estimates endpoint</a> provides the ability to get a rate estimate, create a match,\
    \ update an estimate, or turn an estimate into a match.</p>\n    <p>To receive an estimated rate for a delivery without\
    \ creating the match itself, hit the POST match estimates endpoint.</p>\n    <p>To turn the estimate into a delivery (what\
    \ we call a match at FRAYT), make a call to ouar PATCH match estimates endpoint.</p>\n\n  <h3>Matches </h3>\n    <p>The\
    \ <a href=\"/docs/api/v2.2/#/matches/FraytElixirWeb.API.V2x2.MatchController.estimate\" target=\"matches\">matches endpoint</a>\
    \ provides the ability to create a match, update a match, add a tip, or cancel a match.</p>\n    <p>To tender a delivery\
    \ (what we call a match at FRAYT), pass the required payload to our POST matches endpoint.</p>\n    <p>To fetch data on\
    \ a match at any point, hit the GET /matches/{id} endpoint.</p>\n\n\n<h2>Webhooks</h2>\n  <p>Webhook payloads are defined\
    \ in the callbacks of each method below. You can find detailed state information under the response Schema of each callback.</p>\n\
    \  <p><i>To receive webhook updates from FRAYT, contact the FRAYT team for setup and configuration at <a href=\"mailto:dev@frayt.com\"\
    >dev@frayt.com</a></i></p>\n"
servers:
- url: https://api.frayt.com
  variables: {}
tags:
- name: matches
paths:
  /api/v2.2/matches:
    post:
      callbacks:
        match_update:
          match.shipper.location.company.webhook_url:
            post:
              callbacks: {}
              deprecated: false
              description: Every time the Match state transitions, a child stop state transitions, or the driver's location
                is updated when en route an update will be sent to your configured company webhook. Updates are only sent
                out if webhooks are configured.
              parameters: []
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MatchResponse'
                description: Match
                required: false
              responses:
                '200':
                  description: Your server returns this code if it accepts the callback
              summary: Send back Match transitions
              tags: []
      operationId: FraytElixirWeb.API.V2x2.MatchController.create
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MatchRequest'
        description: Match params
        required: false
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchResponse'
          description: Match response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
          description: No Credentials
        '422':
          content:
            application/json:
              schema:
                oneOf:
                - $ref: '#/components/schemas/Unprocessible Entity'
                - $ref: '#/components/schemas/Invalid Parameters'
                type: object
          description: Invalid parameters
      security:
      - authorization: []
      summary: Create an authorized match
      tags:
      - matches
  /api/v2.2/matches/{id}:
    delete:
      callbacks:
        match_update:
          match.shipper.location.company.webhook_url:
            post:
              callbacks: {}
              deprecated: false
              description: Every time the Match state transitions, a child stop state transitions, or the driver's location
                is updated when en route an update will be sent to your configured company webhook. Updates are only sent
                out if webhooks are configured.
              parameters: []
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MatchResponse'
                description: Match
                required: false
              responses:
                '200':
                  description: Your server returns this code if it accepts the callback
              summary: Send back Match transitions
              tags: []
      operationId: FraytElixirWeb.API.V2x2.MatchController.delete
      parameters:
      - description: Match ID
        example: 44e216c1-3ebc-4ce0-9a6b-1b94d9c2f25b
        in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelMatchRequest'
        description: Cancel params
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchResponse'
          description: Match response
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bad Request'
          description: Bad Request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
          description: No Credentials
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forbidden'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Not Found'
          description: Not Found
      security:
      - authorization: []
      summary: Cancel Match
      tags:
      - matches
    get:
      callbacks: {}
      operationId: FraytElixirWeb.API.V2x2.MatchController.show
      parameters:
      - description: Match ID
        example: 44e216c1-3ebc-4ce0-9a6b-1b94d9c2f25b
        in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchResponse'
          description: Match response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
          description: No Credentials
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forbidden'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Not Found'
          description: Not Found
      security:
      - authorization: []
      summary: Get Match
      tags:
      - matches
    patch:
      callbacks:
        match_update:
          match.shipper.location.company.webhook_url:
            post:
              callbacks: {}
              deprecated: false
              description: Every time the Match state transitions, a child stop state transitions, or the driver's location
                is updated when en route an update will be sent to your configured company webhook. Updates are only sent
                out if webhooks are configured.
              parameters: []
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MatchResponse'
                description: Match
                required: false
              responses:
                '200':
                  description: Your server returns this code if it accepts the callback
              summary: Send back Match transitions
              tags: []
      operationId: FraytElixirWeb.API.V2x2.MatchController.update
      parameters:
      - description: Match ID
        example: 44e216c1-3ebc-4ce0-9a6b-1b94d9c2f25b
        in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RestrictedUpdateMatchRequest'
        description: Update an existing match that has not been picked up yet
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchResponse'
          description: Match response
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bad Request'
          description: Bad Request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
          description: No Credentials
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forbidden'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Not Found'
          description: Not Found
      security:
      - authorization: []
      summary: Update Match
      tags:
      - matches
  /api/v2.2/matches/{match_id}/stops/{stop_id}:
    patch:
      callbacks: {}
      operationId: FraytElixirWeb.API.V2x2.MatchStopController.update
      parameters:
      - description: Match ID
        example: 44e216c1-3ebc-4ce0-9a6b-1b94d9c2f25b
        in: path
        name: match_id
        required: true
        schema:
          type: string
      - description: Stop ID
        example: 44e216c1-3ebc-4ce0-9a6b-1b94d9c2f25b
        in: path
        name: stop_id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDriverTip'
        description: Update the driver's tip at a specific stop
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchStopResponse'
          description: Stop response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
          description: No Credentials
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forbidden'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Not Found'
          description: Not Found
        '422':
          content:
            application/json:
              schema:
                oneOf:
                - $ref: '#/components/schemas/Unprocessible Entity'
                - $ref: '#/components/schemas/Invalid Parameters'
                type: object
          description: Invalid parameters
      security:
      - authorization: []
      summary: Update Driver Tip
      tags:
      - matches
components:
  securitySchemes:
    authorization:
      scheme: bearer
      type: http
  schemas:
    Accessorial:
      description: An add-on service for a shipment
      example:
        key: tsa
      properties:
        key:
          description: Unique key for Accessorial
          type: string
      title: Accessorial
      type: object
    Address:
      description: A Goecoded address
      example:
        address: 708 Walnut Street
        address2: '500'
        city: Cincinnati
        country: United States
        country_code: US
        formatted_address: 708 Walnut Street 500, Cincinnati, Ohio 45202, US
        lat: 39.1043198
        lng: -84.5118912
        name: null
        neighborhood: Central Business District
        state: Ohio
        state_code: OH
        type: address
        zip: '45202'
      properties:
        address:
          description: Address line 1
          type: string
        address2:
          description: Address line 2
          type: string
        city:
          description: City
          type: string
        country_code:
          description: Country
          type: string
        formatted_address:
          description: Combined address components in a human readable string
          type: string
        lat:
          description: Latitude point of address
          format: float
          type: number
        lng:
          description: Longitude point of address
          format: float
          type: number
        name:
          description: The name of this address. This could be a store name, a park, or any other name
          type: string
        neighborhood:
          description: The general neighborhood the address is located in
          type: string
        state:
          description: Full state name
          type: string
        state_code:
          description: State code (e.g. OH)
          type: string
        zip:
          description: Zipcode
          type: string
      title: Address
      type: object
    AddressRequest:
      description: A Goecoded address
      example:
        address: 708 Walnut Street
        address2: '500'
        city: Cincinnati
        country_code: US
        lat: 39.1043198
        lng: -84.5118912
        name: FRAYT HQ
        neighborhood: Central Business District
        state_code: OH
        zip: '45202'
      properties:
        address:
          description: Address line 1
          nullable: false
          type: string
        address2:
          description: Address line 2
          nullable: true
          type: string
        city:
          description: City
          nullable: false
          type: string
        country_code:
          description: Country
          nullable: false
          type: string
        lat:
          description: Latitude point of address
          format: float
          nullable: false
          type: number
        lng:
          description: Longitude point of address
          format: float
          nullable: false
          type: number
        name:
          description: The name of this address. This could be a store name, a park, or any other name
          nullable: true
          type: string
        neighborhood:
          description: The general neighborhood the address is located in
          nullable: true
          type: string
        state_code:
          description: State code (e.g. OH)
          nullable: false
          type: string
        zip:
          description: Zipcode
          nullable: false
          type: string
      required:
      - address
      - city
      - state_code
      - zip
      - country_code
      - lat
      - lng
      title: AddressRequest
      type: object
    Bad Request:
      description: There is an issue with you request
      properties:
        code:
          description: Error code
          type: string
        message:
          description: Human readable message explaining the error
          type: string
      title: Bad Request
      type: object
    Barcode Reading:
      description: ''
      example:
        barcode: 123barcode456
        inserted_at: '2030-01-01T00:19:50Z'
        photo: base64:image
        state: captured
        type: pickup
      properties:
        barcode:
          description: Barcode for Match Stop Item
          type: string
        inserted_at:
          description: The date & time this reading was created
          format: date-time
          type: string
        photo:
          description: Item photo. A photo should be taken when a barcode can't be read
          type: string
        state:
          description: State of reading it could be captured, missing or verified
          enum:
          - captured
          - missing
          - verified
          type: string
        type:
          description: Reading type it could be pickup or delivery
          enum:
          - pickup
          - delivery
          type: string
      title: Barcode Reading
      type: object
    CancelMatchRequest:
      description: DELETE body for canceling a Match
      example:
        cancel_reason: your reason
      properties:
        cancel_reason:
          description: The reason for canceling this Match
          type: string
      title: CancelMatchRequest
      type: object
    Contact:
      description: A contact
      example:
        email: john@smith.com
        name: John Smith
        notify: false
        phone_number: +1 202-555-0199
      properties:
        email:
          description: Contact's email address
          format: email
          nullable: true
          type: string
        name:
          description: Contact's first name and last name
          nullable: false
          type: string
        notify:
          description: Set to `false` if the contact should not receive SMS and email notifications regarding the status of
            this shipment
          nullable: false
          type: boolean
        phone_number:
          description: Contact's phone number in the general international format for telephone numbers (E.164)
          nullable: true
          type: string
      required:
      - name
      title: Contact
      type: object
    Driver:
      description: A Driver
      example:
        current_location:
          created_at: 2020-09-28T09:31
          id: 00021f0f-0ccb-4773-8983-4cb4ef519fab
          lat: 39.109793
          lng: -84.515256
        email: bob@smith.co
        first_name: Bob
        id: 0ff660a4-4866-4382-a008-c942d33e0cb6
        last_name: Smith
        phone_number: '+19998887777'
        vehicle_make: Tesla
        vehicle_model: Cybertruck
        vehicle_year: '2022'
      properties:
        current_location:
          properties:
            created_at:
              description: Date & time of last driver location update
              format: date-time
              type: string
            id:
              description: Unique identifier for driver's location
              type: string
            lat:
              description: Latitude point of driver's location
              format: float
              type: number
            lng:
              description: Longitude point of driver's location
              format: float
              type: number
          type: object
        email:
          description: Email associated with driver
          format: email
          type: string
        first_name:
          type: string
        id:
          description: Unique identifier for driver
          type: string
        last_name:
          type: string
        phone_number:
          description: Driver's phone number
          type: string
        vehicle_make:
          description: Make of the driver's vehicle
          type: string
        vehicle_model:
          description: Model of the driver's vehicle
          type: string
        vehicle_year:
          description: Manufacturing year of the driver's vehicle
          type: string
      title: Driver
      type: object
    Forbidden:
      description: Invalid/expired credentials were provided or permissions are insufficient
      example:
        code: forbidden
        message: string
      properties:
        code:
          description: Error code
          type: string
        message:
          description: Human readable message explaining the error
          type: string
      title: Forbidden
      type: object
    Invalid Parameters:
      description: Error response when invalid paramaters are passed
      properties:
        errors:
          items:
            properties:
              detail:
                type: string
              source:
                properties:
                  pointer:
                    type: string
                type: object
              title:
                type: string
            type: object
          type: array
      title: Invalid Parameters
      type: object
    Label:
      description: A label containing a format and a value used for generating a barcode or QR code.
      example:
        format: qr_code
        value: 1Z2Y3X4W5V6U7
      properties:
        format:
          description: The format of the label
          enum:
          - code_128
          - qr_code
          - code_39
          nullable: false
          type: string
        value:
          description: The value of the label
          nullable: false
          type: string
      title: Label
      type: object
    Match:
      description: A Match
      example:
        accepted_at: null
        accessorials:
        - description: Driver must be certified by the TSA for this Match
          id: 1e261ee8-71b3-480a-908d-168941ccea05
          key: tsa
          name: TSA Certification
        activated_at: null
        arrived_at: null
        bill_of_lading_photo: null
        bill_of_lading_required: false
        cancel_code: null
        cancel_reason: null
        canceled_at: null
        completed_at: null
        contract:
          allowed_cancellation_states:
          - inactive
          - scheduled
          - assigning_driver
          company_id: null
          contract_key: frayt_dash
          id: 346519d2-db50-44ca-b2f7-d50771efc03f
          name: Dash
        coupon: null
        defaults:
          match_stop_items:
            barcode_delivery_required: false
            barcode_pickup_required: false
            type: item
          match_stops:
            cargo_location_required: false
            destination_photo_required: true
            has_load_fee: true
            id_verification_required: false
            needs_pallet_jack: false
            self_recipient: true
            signature_required: true
            signature_type: electronic
          match_stops.recipient:
            notify: false
          matches:
            origin_photo_required: false
            parking_spot_required: false
          matches.sender:
            notify: false
        driver: null
        dropoff_at: '2030-02-01T00:30:00Z'
        eta: null
        fees:
        - amount: 14000
          description: TSA Service Fee
          id: 1e261ee8-71b3-480a-908d-168941ccea05
          name: TSA Certification
          original_amount: 0
          type: tsa_wait_fee
        - amount: 4894
          description: null
          id: 1e261ee8-71b3-480a-908d-168941ccea05
          name: Base Fee
          original_amount: 0
          type: base_fee
        - amount: 1000
          description: null
          id: 1e261ee8-71b3-480a-908d-168941ccea05
          name: Driver Tip
          original_amount: 0
          type: driver_tip
        id: 0000c119-fca6-4531-8b7f-716efb54ef26
        identifier: '1234567890'
        inserted_at: '2030-01-01T00:19:50Z'
        label:
          format: qr_code
          value: 1Z2Y3X4W5V6U7
        optimized_stops: false
        origin_address:
          address: 708 Walnut Street
          address2: '500'
          city: Cincinnati
          country: United States
          country_code: US
          formatted_address: 708 Walnut Street 500, Cincinnati, Ohio 45202, US
          lat: 39.1043198
          lng: -84.5118912
          name: null
          neighborhood: Central Business District
          state: Ohio
          state_code: OH
          type: address
          zip: '45202'
        origin_photo: null
        origin_photo_required: false
        origin_photos: []
        picked_up_at: null
        pickup_at: '2030-02-01T00:00:00Z'
        pickup_notes: Go to the back
        platform: marketplace
        po: ABCDEFG
        preferred_driver: null
        price_discount: 0.0
        rating: null
        rating_reason: null
        required_fields: {}
        route_id: 0000c119-fca6-4531-8b7f-716efb54ef26
        route_identifier: Huntsville - North East, AL
        route_index: 0
        schedule_id: null
        scheduled: true
        self_sender: false
        sender:
          email: john@smith.com
          id: 23e534a0-b239-41d9-aa00-3adb40197388
          name: John Smith
          notify: false
          phone_number: +1 202-555-0199
        service_level: 1
        shortcode: ABCDEFGH
        signature_photo: null
        slas:
        - completed_at: null
          end_time: '2030-02-01T00:30:00Z'
          start_time: '2030-02-01T00:00:00Z'
          type: pickup
        - completed_at: null
          end_time: '2030-02-01T01:30:00Z'
          start_time: '2030-02-01T00:00:00Z'
          type: delivery
        state: scheduled
        state_transition:
          from: pending
          match_id: 123e4567-e89b-12d3-a456-426614174000
          notes: null
          stop_id: null
          to: scheduled
          updated_at: '2030-01-01 09:30:00'
        stops:
        - arrived_at: null
          cargo_location: null
          cargo_location_required: false
          delivered_at: null
          delivery_notes: Leave by the door
          destination_address:
            address: 708 Walnut Street
            address2: '500'
            city: Cincinnati
            country: United States
            country_code: US
            formatted_address: 708 Walnut Street 500, Cincinnati, Ohio 45202, US
            lat: 39.1043198
            lng: -84.5118912
            name: null
            neighborhood: Central Business District
            state: Ohio
            state_code: OH
            type: address
            zip: '45202'
          destination_photo: null
          destination_photo_required: false
          destination_photos: []
          driver_tip: 10.0
          dropoff_by: '2030-01-01T01:01:00Z'
          electronic_bill_of_lading_photo: null
          eta: null
          has_load_fee: true
          id: c22206a8-00f5-4fde-8395-c24441263f1b
          id_birthdate: null
          id_verification_required: true
          id_verified_at: null
          identifier: '1234567890'
          index: 0
          items:
          - barcode: 123barcode456
            barcode_delivery_required: true
            barcode_pickup_required: false
            barcode_readings: []
            container_barcode: 123container456
            declared_value: 1500
            description: A Tire
            height: 30.0
            id: 03e534a0-b239-41d9-aa00-3adb40197388
            length: 30.0
            pieces: 4
            stop_id: '123'
            type: item
            volume: 5400
            weight: 25.0
            width: 6.0
          minimum_age: 42
          needs_pallet_jack: false
          po: PO or Job Number for this Match Stop
          recipient:
            email: john@smith.com
            id: 13e534a0-b239-41d9-aa00-3adb40197388
            name: John Smith
            notify: false
            phone_number: +1 202-555-0199
          route_index: 1
          self_recipient: false
          signature_instructions: null
          signature_name: null
          signature_photo: null
          signature_required: false
          signature_type: electronic
          state: pending
          state_transition: null
          timeframe:
            estimated: null
            planned:
              earliest_arrival: '2022-10-01 11:45:10'
              end_time: '2022-10-01 11:45:10'
              latest_arrival: '2022-10-01 11:45:10'
              latest_completion: '2022-10-01 12:00:10'
              start_time: '2022-10-01 11:45:10'
              updated_at: '2022-10-01 11:45:10'
            scheduled:
              earliest_arrival: '2022-10-01 11:45:10'
              end_time: '2022-10-01 11:45:10'
              latest_arrival: '2022-10-01 11:45:10'
              latest_completion: '2022-10-01 12:00:10'
              start_time: '2022-10-01 11:45:10'
              updated_at: '2022-10-01 11:45:10'
          tracking_url: https://example.com/track/1234567890
          travel_duration: 153
          undeliverable_at: null
          undeliverable_code: null
        timeframe:
          estimated: null
          planned:
            earliest_arrival: '2022-10-01 11:45:10'
            end_time: '2022-10-01 11:45:10'
            latest_arrival: '2022-10-01 11:45:10'
            latest_completion: '2022-10-01 12:00:10'
            start_time: '2022-10-01 11:45:10'
            updated_at: '2022-10-01 11:45:10'
          scheduled:
            earliest_arrival: '2022-10-01 11:45:10'
            end_time: '2022-10-01 11:45:10'
            latest_arrival: '2022-10-01 11:45:10'
            latest_completion: '2022-10-01 12:00:10'
            start_time: '2022-10-01 11:45:10'
            updated_at: '2022-10-01 11:45:10'
        timezone: America/New_York
        total_distance: 1.7
        total_price: 198.94
        total_vo

# --- truncated at 32 KB (116 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/frayt/refs/heads/main/openapi/frayt-matches-openapi.yml