Skip to main content
Webhooks tell your system when an order, tracking snapshot, file list, or inspection report changes. Each request uses CloudEvents 1.0 and the Standard Webhooks signature format. Use the event to start work, then read data.resource_url when that work needs the complete current resource.

Build the receiver

Your endpoint must follow this order:
  1. Read the request body as raw bytes.
  2. Verify the timestamp and signature.
  3. Store the event with its id as the idempotency key.
  4. Return a 2xx status after durable storage.
  5. Read the related resource outside the request path.
Return a successful status for a duplicate event.
Verify the signature before you parse the body. A parse and serialize cycle changes the signed bytes.

Verify the signature

The request contains three signature headers. Remove the whsec_ prefix from the secret, then decode the remaining value as Base64. Join the webhook ID, timestamp, and raw body with full stops. Calculate HMAC-SHA256 and compare the Base64 result in constant time. This complete Node.js function returns the parsed event only after verification.
Use a maintained Standard Webhooks library when your language has one.
Check that the receiver uses the raw body, the correct environment secret, and a timestamp in seconds. Keep the whsec_ prefix in storage, but remove it before Base64 decoding.

Process events in order

Webhook delivery is at least once. Delivery order can differ from event order. Deduplicate by event id. Use data.order_sequence to order events for one order. Use data.ordered_for to route an ordering-channel event. The value is null for a direct customer order. Resolve data.resource_url and data.related_resource_urls against the origin in the event source. Order events point to the order. Tracking, file, and inspection events point to their related resources.

Event types

An item event also reports the resulting order summary change. Bahn does not send an additional order status event for the same transition. A cancellation event does not cause an additional order status event.

ETA and tracking events

Bahn sends an ETA event when an ETA appears, disappears, changes by 15 minutes or more, or crosses a target boundary. Small ETA changes accumulate from the last notified ETA. Read the order before you send a customer message or store the new ETA. Bahn does not send a webhook for each position. Poll tracking while a map is open and use the ETag.

Retries and replay

Bahn sends up to eight retries after the first failed attempt. The delays grow from one minute to 24 hours. The customer portal shows delivery attempts and errors. It keeps completed delivery history for 30 days. You can replay a retained event only to the endpoint that received it. The replay keeps the event ID. Use a separate endpoint and signing secret for each environment.