DOCS

Webhooks

Listen to events with webhooks

Get real-time event notifications for your Zonos integration.

Webhooks provide a way for Zonos to proactively notify your external systems whenever certain events take place. When the subscribed event occurs, Zonos will send an HTTP POST request to the webhook URL you specify. The request body will contain the event details, allowing your system to handle the event programmatically.

Webhooks are useful for integrating Zonos with other platforms, triggering automated workflows, and keeping data in sync across systems in real-time. For example, you could use webhooks to:

  • Update your order management system when an order is created in Zonos
  • Notify your fulfillment provider when a shipment is canceled
  • Log status changes of international orders for auditing purposes

Webhook types 

All available webhook types are included in the WebhookType enum. Example payloads for each can be found in our Event Types guide.

Creating webhooks 

To create a webhook via the API:

1mutation WebhookCreate($input: WebhookCreateInput!) {
2 webhookCreate(input: $input) {
3 id
4 url
5 type
6 status
7 secret
8 headers {
9 key
10 }
11 }
12}

Important: Save the secret value when you create the webhook — it's only returned here, and you'll need it to verify webhook signatures. See Verifying webhook signatures below.

Edit webhook details 

To edit an existing webhook via the API:

1mutation WebhookUpdate($input: WebhookUpdateInput!) {
2 webhookUpdate(input: $input) {
3 id
4 url
5 type
6 status
7 }
8}

Verifying webhook signatures 

Every webhook request Zonos sends includes a zonos-signature header so you can confirm the request actually came from Zonos and that the payload wasn't altered in transit.

The header value has the format:

timestamp=<unix-timestamp-ms>,hmac=<base64-encoded-signature>
  • timestamp — the time, in Unix epoch milliseconds, the request was signed.
  • hmac — an HMAC-SHA256 signature of the raw JSON request body, computed using your webhook's secret as the key and Base64-encoded.

To verify a request:

  1. Parse the timestamp and hmac values out of the zonos-signature header.
  2. Compute your own HMAC-SHA256 signature over the raw, unparsed request body, using the secret you received when you created the webhook.
  3. Compare your computed signature to the hmac value using a constant-time comparison, and reject the request if they don't match.
  4. Optionally reject requests where timestamp is older than a few minutes to guard against replay of a captured request. Zonos doesn't enforce a delivery window itself, so this check is up to you.
1const crypto = require("crypto");
2 
3function verifyZonosWebhook(rawBody, signatureHeader, secret) {
4 const [timestampPart, hmacPart] = signatureHeader.split(",");
5 const receivedHmac = hmacPart.split("=")[1];
6 
7 const expectedHmac = crypto
8 .createHmac("sha256", secret)
9 .update(rawBody)
10 .digest("base64");
11 
12 const receivedBuffer = Buffer.from(receivedHmac);
13 const expectedBuffer = Buffer.from(expectedHmac);
14 
15 if (receivedBuffer.length !== expectedBuffer.length) {
16 return false;
17 }
18 
19 return crypto.timingSafeEqual(receivedBuffer, expectedBuffer);
20}

Note: If you configured custom headers on your webhook, those are also included verbatim on every request alongside zonos-signature.

View webhook logs 

To view webhook logs via the API:

1query WebhookLogs(
2$first: Int
3$after: String
4$filter: WebhookLogsFilterInput
5) {
6 webhookLogs(first: $first, after: $after, filter: $filter) {
7 edges {
8 node {
9 id
10 type
11 url
12 createdAt
13 responseStatus
14 }
15 }
16 }
17}
GraphQL API ReferenceTypes, inputs, and operations used in this guide
Book a demo

Was this page helpful?