Best practices

Patterns for reliable, secure webhook handling
Available onProEnterprise

A few habits make webhook integrations robust. Follow these when building your handler.

Acknowledge fast, then do the work

Return a 2xx status immediately to acknowledge receipt, then do any heavy work (fetching rates, updating your database) asynchronously. Slow handlers risk timing out before they acknowledge.

Treat the payload as a trigger

After a rate.updated event, call the Ziptax rate API to fetch the authoritative updated rates for the indicated authority. Do not treat the webhook body as the source of truth for rate values. It only tells you which authority changed.

Make handlers idempotent

Be prepared to receive the same event more than once. Design your handler so that processing a duplicate event is harmless (for example, key your work off the authority in the payload rather than blindly appending records).

Verify authenticity

Use your signing secret to confirm requests are genuinely from Ziptax once the verification scheme is published. Until then, keep your endpoint URL private and rely on re-fetching authoritative data from the API.

Use HTTPS

Serve every production endpoint over https://. This protects the payload in transit and is required for a secure integration.

A minimal receiver

The same handler is shown below in Node.js, Python, and Go. Use the tabs to switch languages. Each one acknowledges quickly with a 2xx, then treats the event as a trigger to re-fetch rates for the indicated authority. These are illustrative starting points; adapt them to your stack.

1import express from "express";
2
3const app = express();
4app.use(express.json());
5
6app.post("/webhooks/ziptax", (req, res) => {
7 // TODO: verify the X-Signature header using your Ziptax signing secret (whsec_...)
8 // See "Verify & secure deliveries" for a full example.
9
10 const { event, data } = req.body;
11
12 if (event === "rate.updated") {
13 const { locality, code } = data.rateUpdateDetail;
14 // A rate changed for this authority. Fetch the latest rates from the Ziptax API.
15 console.log(`Rate updated for ${locality} ${code}`);
16 }
17
18 // Acknowledge quickly.
19 res.sendStatus(200);
20});
21
22app.listen(3000);

This minimal receiver leaves signature verification as a TODO to stay short. In production, verify the X-Signature header before trusting a delivery. See Verify & secure deliveries for a full example.