Shipping Webhooks: Automate Your Logistics Stack with Real-Time Events
Polling APIs for changes wastes quota and reacts late. Webhooks push events — rate calculations, key changes, billing updates — to your systems in real time. Architecture, security (HMAC) and retry handling explained.

There are two ways to know something changed in an external system: ask repeatedly, or be told. Polling burns API quota, adds latency, and still misses things between polls. Webhooks invert the flow — the platform calls you, within seconds, exactly once per event. Here is how to use them well in a shipping stack.
What events look like
Postpin emits webhooks for the events that matter operationally:
- rate.calculated — a keyed rate call completed (feed analytics or margin monitoring)
- key.created / key.revoked — API key lifecycle (security audit trails)
- invoice.paid / subscription.updated — billing changes (sync your internal ledgers)
- sync.completed / sync.failed — the nightly pincode sync finished (refresh your caches)
Each delivery is a signed JSON POST to your endpoint with the event name, timestamp and payload.
Verify signatures — always
Anyone can POST JSON at your endpoint. The signature header proves it came from the platform and was not tampered with:
X-Postpin-Signature: t=1767854301,v1=<hmac>
Verification is five lines:
const [t, v1] = parseHeader(req.headers["x-postpin-signature"]);
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(t + "." + rawBody) // raw body, not re-serialised JSON!
.digest("hex");
if (!timingSafeEqual(expected, v1)) return res.status(401).end();
Two classic bugs to avoid: verifying against a re-serialised body (key order changes break the HMAC — use the raw bytes), and skipping the timestamp check (replay protection: reject events older than a few minutes).
Design for retries
Deliveries fail — your pod restarts, a deploy is mid-flight. Well-behaved platforms retry with backoff (Postpin makes 3 attempts per delivery and tracks your endpoint's success rate). Your side of the contract:
- Return 2xx fast. Acknowledge in milliseconds, process async. A webhook handler that does heavy work inline will time out and trigger spurious retries.
- Be idempotent. Retries mean duplicates. Key your processing on the event id, not "message received".
- Tolerate disorder. Two events can arrive out of order; use the event timestamp, not arrival time, when sequencing matters.
The cache-refresh pattern
The highest-value shipping webhook is the least glamorous: sync.completed. If you cache serviceability or rate responses (you should), the nightly pincode sync is exactly when caches go stale. Subscribe, and on each event flush the relevant keys:
case "sync.completed":
await redis.del(...await redis.keys("serviceability:*"));
Your caches now expire on truth changes instead of arbitrary TTLs — fresher data and fewer API calls simultaneously.
Production checklist
- [ ] HTTPS endpoint, HMAC verified on raw body, timestamp checked
- [ ] Sub-second 2xx acknowledgement; processing queued
- [ ] Idempotency by event id
- [ ] Endpoint success rate monitored (Postpin shows it per endpoint); alerts on failures
- [ ] Secret rotation procedure tested (roll-secret endpoint, dual-accept window)
Webhooks are a small integration with outsized returns: your logistics stack stops asking "anything new?" and simply reacts. Set up your first endpoint from the dashboard in about five minutes — the docs cover every event schema.
Frequently asked questions
What is the difference between webhooks and API polling?
Polling asks the API "anything new?" on a timer — most calls return nothing, and changes are only noticed on the next tick. Webhooks reverse the direction: the platform POSTs the event to your endpoint seconds after it happens. Less traffic, lower latency, no missed windows.
How do I secure a webhook endpoint?
Serve HTTPS, verify the HMAC signature on the raw request body, and reject stale timestamps to block replays. Never process an unverified payload — an open webhook endpoint is an unauthenticated write API into your systems.
What happens if my endpoint is down when an event fires?
Good platforms retry with backoff — Postpin attempts each delivery up to 3 times and tracks your endpoint's success rate so you can see degradation in the dashboard. Design your handler to be idempotent so retries and replays are harmless.
