webhooksautomationdevelopersapi

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.

P
Postpin Team3 min read
Shipping Webhooks: Automate Your Logistics Stack with Real-Time Events

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:

  1. Return 2xx fast. Acknowledge in milliseconds, process async. A webhook handler that does heavy work inline will time out and trigger spurious retries.
  2. Be idempotent. Retries mean duplicates. Key your processing on the event id, not "message received".
  3. 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.