Enterprise Freight Technology

How BtSh sends freight status back to your ERP.

A webhook is BtSh calling your system when something important changes. It removes the need for logistics teams to keep refreshing dashboards or for ERPs to poll continuously.

Webhooks in one sentence

Instead of your ERP asking BtSh “has anything changed?” every few minutes, BtSh sends an HTTPS POST to an endpoint your company registers, the moment a load or trip changes state. Your integration reads the event and updates the matching shipment row in SAP, Oracle, Microsoft Dynamics or your TMS.

Load or trip changes
BtSh signs the event
POST to your endpoint
Your ERP updates
2xx = delivered

Which events BtSh sends

Events cover the commercial life of a load, the physical trip and the paperwork that follows. Typical subscriptions for an enterprise shipper:

load.created            load.matched
load.escrow_funded      load.pickup_confirmed
load.in_transit         load.delivered
load.completed          load.cancelled
load.exception
trip.arrived_pickup     trip.departed_pickup
trip.near_delivery      trip.arrived_destination
trip.delay_detected     trip.route_deviation
document.pod_available
payment.received        payment.failed

Most ERPs only need a handful: load.matched to show a truck is assigned, load.in_transit and trip.near_delivery for the warehouse, and load.delivered plus document.pod_available to close the shipment and trigger invoicing.

What each delivery looks like

Every delivery is a JSON body with headers that tell your system exactly what it received:

POST https://erp.yourcompany.com/btsh/webhooks
Content-Type: application/json
User-Agent: BtSh-Connect/1.0
X-BTSH-Event: load.delivered
X-BTSH-Event-Id: ...
X-BTSH-Delivery-Id: ...
X-BTSH-Timestamp: 1767225600
X-BTSH-Signature: sha256=...

How to trust it: verify the signature

Each endpoint has its own signing secret. BtSh computes an HMAC-SHA256 over the timestamp, a full stop and the raw request body, and sends it as X-BTSH-Signature. Your integration repeats the same calculation with its copy of the secret and rejects anything that does not match — so a forged “delivered” event can never close a shipment in your ERP.

expected = "sha256=" + HMAC_SHA256(secret, timestamp + "." + raw_body)
accept only if expected == X-BTSH-Signature
Use the raw body.
Verify the signature against the exact bytes received, before parsing or re-serialising the JSON. Also reject timestamps that are too old, so a captured request cannot be replayed later.

What happens if your system is down

A delivery counts as successful only when your endpoint answers with a 2xx status. If it times out or returns an error, BtSh retries on a widening schedule — after about 1 minute, 5 minutes, 15 minutes, 1 hour, 6 hours and 24 hours. After the final attempt the delivery is parked as dead-letter, visible to your integration team, rather than silently lost.

Make your handler idempotent

Because of retries, the same event can arrive more than once. Store the X-BTSH-Event-Id you have processed and ignore repeats. Reply with 2xx quickly and do heavy ERP work in the background, so slow processing is never mistaken for a failed delivery.

Webhooks plus the Loads API

Webhooks are the return path. Loads go in through the BtSh Loads API (one authenticated request per shipment, with an idempotency key), and status comes back through webhooks — so the ERP stays the system of record while BtSh executes the freight. Read how your ERP can send freight directly to BtSh for the first half of the integration.

Planning an enterprise freight integration?

BtSh corporate workspaces and production API access are provisioned through our enterprise onboarding team.

Explore BtSh Enterprise Shipping