Best Practices for Webhooks

Review these best practices to help keep your webhooks secure and function seamlessly with your integration. To find out more about setting up and receiving webhooks, visit the Webhooks guide.

Webhook security

There are a few measures that can be taken to ensure webhooks are secure. Only HTTPS URLs are supported and require a valid SSL certificate. Self-signed certificates are not supported.
Below are some additional security-related methods:

IP whitelistingWhitelist the following IPs that webhooks will be sent from, noting the different environments:


URL obfuscationWhen creating a webhooks POST endpoint, use an obfuscated URL to ensure it cannot be easily accessed by an insecure source.
For example:
Secondary API callUsing the ID provided within the webhook, you can initiate another API call to fetch the resource from Zai once again. This ensures the request and response occur between both backends. Example: A webhook of GET /items/:id reaches the endpoint. In the payload, there is an ID. Using the ID, make a call to GET /items/:id to ensure the data is coming from the Zai API.

Verify events are sent from Zai

Verify webhook signatures to ensure that events received are sent from Zai.

Retry feature

Webhook jobs will be automatically retried in case they fail to be delivered. Our application will automatically re-attempt to send webhook notifications to customers for up to 24 hours with an exponential backoff capability.


Please note

In some cases, when a failed webhook is retried, it could be sent after a more recent update. For example, if an update happens in our system at 10:00am, and the webhook that's sent fails, then we attempt to send the same data again from the 10:00am update. If that retry attempt is sent at 10:05, there’s a chance that another update happened at 10:02am and it was successful. In this case, you’d have the latest data from 10:02am and you should discard any webhook data referring to the earlier update from 10:00am.

You can check a webhook payload’s updated_at field to determine whether the data is newer or older than the data that you currently have stored in your system.
For example, when receiving a Users webhook payload, you could compare your own data against the users.updated_at field. Similarly, when receiving a Batch Transactions webhook payload, you could compare your own data against the batch_transactions.updated_at field.

Retry attemptsEstimated retry timings
15 minutes
225 minutes
31 hour & 45 minutes
47 hours & 5 minutes
528 hours & 25 minutes



In the event that the maximum number of automatic retry attempts is exhausted, we’ve maintained the ability for our internal team members to manually resend failed webhook notifications.
In the future, we will expose features to allow enhanced searching of webhooks and the ability to retrigger a failed webhook via an API.


There are a number of ways to start testing Webhooks with Zai. We recommend services such as Request Bin, Runscope and/or, all of which can be used to provide a container for all webhooks to be sent to.