Added

Webhook Events for Load & Trip Status Updates

What's New?

We've added two new webhook event types to the Public API: load.status.changed and trip.status.changed. Whenever a load or trip transitions from one status to another (for example, Covered → Dispatched or Dispatched → InTransit), Alvys now pushes a real-time webhook to every active subscription that selected those events.

What Changed?

Previously, the Public API exposed webhooks only for tender lifecycle events. Detecting load- and trip-level status transitions required polling GET /loads and GET /trips on a schedule.

Now, the following event types are available alongside the existing tender.* events and can be selected when creating or editing a webhook subscription:

load.status.changed
trip.status.changed

The full list is also returned by:

GET /p/v1.0/webhooks/event-types

Event Envelope

All webhook deliveries share the standard Alvys envelope. The new event types reuse it without changes:

{
  "id": "…",
  "type": "load.status.changed",
  "timestamp": "2026-05-04T14:32:11.482Z",
  "version": "1",
  "data": { /* event-specific payload — see below */ }
  // Other envelope fields are omitted from this example for brevity.
}

The envelope id is unique per event and should be used as the idempotency key on the consumer side.

load.status.changed

Triggered when a load transitions from one status to another. The payload carries the prior + current status delta and a full Public-API load snapshot — the same shape returned by GET /p/v1.0/loads/{loadNumber}.

{
  "previousStatus": "Covered",
  "status": "Dispatched",
  "load": {
    "id": "…",
    "loadNumber": "1006321",
    "status": "Dispatched"
    // Full Public-API load object — same fields as GET /p/v1.0/loads/{loadNumber}.
    // Other fields (customer, stops, charges, references, etc.) omitted here for brevity.
  }
}

trip.status.changed

Triggered when a trip transitions from one status to another. The payload carries the prior + current status delta and a full Public-API trip snapshot — the same shape returned by GET /p/v1.0/trips/{tripId}.

{
  "previousStatus": "Dispatched",
  "status": "InTransit",
  "trip": {
    "id": "…",
    "tripNumber": "T-1006321-1",
    "status": "InTransit"
    // Full Public-API trip object — same fields as GET /p/v1.0/trips/{tripId}.
    // Other fields (driver, truck, stops, accessorials, etc.) omitted here for brevity.
  }
}

Behavior

  • Events are emitted only on actual transitions — when status differs from previousStatus. No-op writes do not generate deliveries.
  • load / trip may be null if the snapshot read fails or if the payload exceeded the size limit and was stripped. The previousStatus and status fields are always present so consumers can still react to the transition and refetch via GET /loads/{id} or GET /trips/{id} if needed.
  • Deliveries are signed (X-Alvys-Signature), retried with exponential backoff, and auto-disable subscriptions after sustained failures — identical to existing tender.* events.

Endpoints Affected

  • GET /p/v1.0/webhooks/event-types — now returns load.status.changed and trip.status.changed
  • POST /p/v1.0/webhooks / PUT /p/v1.0/webhooks/{id} — accept the new event type values in the eventTypes array

No request/response shapes were changed for existing endpoints. This update is fully backward compatible.

Why?

These events let API partners and integrations:

  • React to load and trip status changes in real time, without polling
  • Reduce overall API call volume on /loads and /trips
  • Drive downstream automations (factoring, tracking, billing) the moment an operational state changes
  • Keep audit trails consistent through the existing webhook Delivery Logs UI

This update extends the Public API's webhook surface with operational lifecycle coverage while preserving the existing event envelope contract.