FRAYT · AsyncAPI Specification

Frayt Match Webhooks

Version

View Spec View on GitHub CompanyLast Mile DeliveryLogisticsCourierOn Demand DeliveryShippingFreightSupply ChainTransportationThird Party LogisticsDelivery TrackingWebhooksAsyncAPIWebhooksEvents

AsyncAPI Specification

Raw ↑
generated: '2026-08-16'
method: derived
source: openapi/_original/frayt-api-openapi-original.json (OpenAPI callbacks) + https://api.frayt.com/docs/api/v2.2
spec_type: null
note: >-
  FRAYT publishes NO AsyncAPI document — probed /asyncapi.yaml, /asyncapi.json and
  the docs host, all 404. It DOES ship a real, machine-readable webhook contract, and
  in an unusually good place: the webhook is declared as an OpenAPI 3.0 `callbacks`
  object on three operations, with the payload bound by $ref to the same
  MatchResponse schema the GET returns. That means a webhook subscriber can generate
  its receiver directly from the published spec — a stronger position than most
  providers who describe webhooks only in prose. This artifact is the derived
  catalog of that surface; it is not an AsyncAPI document and is not presented as one.
surface:
  transport: http
  direction: provider-to-subscriber
  delivery: POST to a single fixed subscriber URL
  subscription_model: provider-configured
  subscription_note: >-
    There is NO self-service webhook subscription API. The destination is stored on
    the FRAYT side as `match.shipper.location.company.webhook_url` and is configured
    by the FRAYT team — the docs say "To receive webhook updates from FRAYT, contact
    the FRAYT team for setup and configuration at dev@frayt.com". One URL per
    company location, optional custom headers on the payload.
  payload_schema: MatchResponse
  payload_note: >-
    The webhook body is byte-for-byte the same envelope as GET /api/v2.2/matches/{id}
    — `{"response": {...Match...}}` — so one parser serves both surfaces.
  expected_response: 'HTTP 200 from the subscriber acknowledges the callback'
  retries: undocumented
  signing: undocumented
  note_security: >-
    FRAYT documents no HMAC signature, no shared secret and no replay protection on
    webhook delivery; the only stated authentication affordance is optional custom
    headers included in the payload configuration. Subscribers should treat the
    payload as unauthenticated and re-read the Match via GET before acting on it.
events:
- name: match_update
  declared_on:
  - openapi/frayt-matches-openapi.yml#FraytElixirWeb.API.V2x2.MatchController.create
  - openapi/frayt-matches-openapi.yml#FraytElixirWeb.API.V2x2.MatchController.update
  - openapi/frayt-matches-openapi.yml#FraytElixirWeb.API.V2x2.MatchController.delete
  summary: Send back Match transitions
  description: >-
    Fires every time the Match state transitions, a child stop state transitions, or
    the driver's location is updated while en route. Only sent when webhooks are
    configured for the company.
  payload: MatchResponse
  triggers:
  - match state transition
  - match stop state transition
  - driver location update while en route
match_states:
  field: response.state
  transition_record: response.state_transition (from, to, notes, match_id, stop_id, updated_at)
  happy_path: [pending, inactive, scheduled, assigning_driver, offered, accepted, en_route_to_pickup,
    arrived_at_pickup, picked_up, completed, charged]
  enum: [accepted, admin_canceled, arrived_at_pickup, arrived_at_return, assigning_driver,
    canceled, charged, completed, driver_canceled, en_route_to_pickup, en_route_to_return,
    inactive, offer_not_accepted, offered, pending, picked_up, scheduled, unable_to_pickup]
  terminal: [charged, admin_canceled, canceled, unable_to_pickup]
  note: >-
    `driver_canceled` is NOT terminal — the driver removed themselves and FRAYT
    re-offers the Match to the marketplace. Subscribers that treat it as a failure
    will cancel deliveries that were about to succeed.
stop_states:
  field: response.stops[].state
  happy_path: [pending, en_route, arrived, signed, delivered]
  enum: [arrived, delivered, en_route, pending, re_routed, returned, signed, undeliverable, unserved]
probes:
- {url: 'https://api.frayt.com/asyncapi.yaml', status: 404}
- {url: 'https://api.frayt.com/asyncapi.json', status: 404}
- {url: 'https://www.frayt.com/asyncapi.yaml', status: 404}