Skip to main content

Purpose

Trailflow supports outbound webhook subscriptions for near-real-time event delivery. Webhook endpoints are managed through the canonical Partner API:
  • POST /v1/webhooks
  • GET /v1/webhooks
  • DELETE /v1/webhooks/{id}

Supported Event Types

Currently emitted event types:
  • load.created
  • load.updated
  • load.status_changed
Partners should subscribe only to the event types they actively consume.

Creating A Subscription

Create a subscription with:
curl --request POST \
  --url 'https://api.trailflow.ai/v1/webhooks' \
  --header 'Authorization: Bearer <api key>' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: wh_20260321_001' \
  --data '{
    "url": "https://partner.example/webhooks/trailflow",
    "eventTypes": ["load.created", "load.status_changed"]
  }'
Request body:
{
  "url": "https://partner.example/webhooks/trailflow",
  "eventTypes": ["load.created", "load.status_changed"]
}
Successful create response:
{
  "data": {
    "id": "whsub_123",
    "url": "https://partner.example/webhooks/trailflow",
    "eventTypes": ["load.created", "load.status_changed"],
    "signingSecret": "tfwhsec_example_secret"
  },
  "requestId": "req_126"
}
Delivery payloads use the same serialized load object described in the main API contract. Trailflow does not currently wrap webhook bodies in a separate event envelope or add requestId to the webhook payload body itself. Use X-Trailflow-Event to distinguish whether the delivery represents load.created, load.updated, or load.status_changed. Example load.created delivery body:
{
  "id": "load_123",
  "externalId": "tt_456",
  "orderNumber": "ORD-1001",
  "status": "ASSIGNED",
  "eligibleForTracking": true,
  "customerId": "customer_1",
  "carrierId": "carrier_1",
  "createdAt": 1710802000000,
  "updatedAt": 1710802000000
}
Example load.status_changed delivery body:
{
  "id": "load_123",
  "externalId": "tt_456",
  "orderNumber": "ORD-1001",
  "status": "DELIVERED",
  "eligibleForTracking": false,
  "customerId": "customer_1",
  "carrierId": "carrier_1",
  "createdAt": 1710802000000,
  "updatedAt": 1710810000000
}

Delivery Headers

Trailflow sends these headers on each delivery:
  • Content-Type: application/json
  • X-Trailflow-Delivery-Id
  • X-Trailflow-Event
  • X-Trailflow-Timestamp
  • X-Trailflow-Signature

Signature Verification

Each subscription has its own signing secret. signingSecret is returned only when the subscription is created. Trailflow does not expose it again from the list endpoint, so partners must store it securely at creation time. Trailflow computes the delivery signature as:
hex(HMAC_SHA256(signingSecret, "<timestamp>.<raw request body>"))
Verification requirements:
  1. read the raw request body exactly as delivered
  2. read X-Trailflow-Timestamp
  3. compute HMAC-SHA256 over <timestamp>.<raw body>
  4. compare the hex digest to X-Trailflow-Signature
X-Trailflow-Delivery-Id is the stable delivery identifier for the attempted send. Use it to record deduplication state across retries and support-coordinated replays. Do not:
  • parse and re-serialize the JSON body before verification
  • log the subscription signing secret
  • send signing secrets in tickets, screenshots, or email

Delivery Behavior

Current behavior:
  • non-2xx responses are treated as failures
  • network failures are treated as failures
  • retries are bounded
  • replay can be requested through Trailflow support after remediation
  • delivery order is best-effort only; retries and parallel scheduling can result in out-of-order arrival across events
Current retry posture:
  • maximum attempts: 3
  • retry delays: approximately 1 minute, then 5 minutes

Subscription Lifecycle

GET /v1/webhooks returns active subscriptions for the calling API client. DELETE /v1/webhooks/{id} disables the subscription from future deliveries. Deletion does not erase historical delivery records retained for support and compliance.

Endpoint Expectations

Partners should operate webhook endpoints that:
  • accept HTTPS POST requests
  • can return a 2xx response quickly after basic validation
  • process duplicate deliveries safely using X-Trailflow-Delivery-Id
  • tolerate retries and temporary Trailflow replays
If downstream work is expensive, acknowledge first and process asynchronously.

Debugging Delivery Failures

When debugging with Trailflow support, include:
  • customer organization
  • approximate delivery timestamp
  • event type
  • webhook URL
  • returned HTTP status code if known
  • requestId from related API calls if applicable
Common failure sources:
  • invalid or rotated signing secret
  • signature verification over a parsed body instead of the raw body
  • slow endpoint responses
  • partner-side 429 or 5xx responses
  • subscription disabled after repeated failures or manual intervention