ShipBob webhooks automatically notify your app when key events occur, allowing you to keep your data in sync.
2XX HTTP response is required to confirm webhook receipt.order.shipped and order.shipment.delivered events to provide live tracking updates to customers.order.shipment.tracking.updated events to receive all shipment status changes (InTransit, OutForDelivery, Delivered, etc.).order.shipment.exception events to detect and respond to stock shortages.return.completed events to update your system when a return has successfully been processed and completed by ShipBob.billing.charge.created events to update your system when a billing transaction has been invoiced.ShipBob sends webhook notifications with the following headers:
Each webhook call includes three headers used for verification:
The content to sign is composed by concatenating the id, timestamp and payload, separated by the full-stop character (.). In code, it will look something like:
Where body is the raw request body. The signature is sensitive to any changes, so even a small change in the body will cause the signature to be completely different. This means that you should not change the body in any way before verifying.
ShipBob uses HMAC with SHA-256 to sign the webhooks.
To calculate the expected signature, you should HMAC the signed_content from above using the base64-decoded bytes of your signing secret as the key. Specifically, take the portion after the whsec_ prefix, base64-decode it, and use the decoded bytes as the HMAC key. For example, given the secret whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw, you would base64-decode MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw and use the resulting bytes as the key.
For example, this is how you can decode the secret and calculate the signature in Node.js:
This generated signature should match one of the signatures sent in the webhook-signature header.
The webhook-signature header is composed of a list of space-delimited signatures and their corresponding version identifiers. The signature list is most commonly of length one, though there could be any number of signatures. For example:
Be sure to remove the version prefix (e.g. v1,) before verifying the signature.
Security Note: It is recommended to use a constant-time string comparison method in order to prevent timing attacks.
✨ The best way to see examples of webhook payloads is to create a webhook in the ShipBob Dashboard by going to:
Integrations → Webhooks → Create new subscription.
order.shipped or return.completed.This approach makes it easy to test your integration, validate your endpoint, and understand the exact payload format without waiting for a real event to occur.
Each message is attempted based on the following schedule, where each period is started following the failure of the preceding attempt:
If an endpoint is removed or disabled delivery attempts to the endpoint will be disabled as well.
For example, an attempt that fails three times before eventually succeeding will be delivered roughly 35 minutes and 5 seconds following the first attempt.
Indicating successful delivery
The way to indicate that a webhook has been processed is by returning a 2xx (status code 200-299) response to the webhook message within a reasonable time-frame (15s). Any other status code, including 3xx redirects are treated as failures.
Failed delivery handling
After the conclusion of the above attempts the message will be marked as Failed for this endpoint, and the webhook sender’s account will get email notification for notifying them of this error.
Manual retries
You can also use the application portal to manually retry each message at any time, or automatically retry (“Recover”) all failed messages starting from a given date.
If all attempts to a specific endpoint fail for a period of 5 days, the endpoint will be disabled and an email will be sent to the account owner. The clock only starts after multiple deliveries fail within a 24-hour span, with at least 12 hours difference between the first and the last failure.
In case your webhook receiving endpoint is behind a firewall or NAT, you may need to allow traffic from static IP addresses.
This is the full list of IP addresses that webhooks may originate from.
✅ Use HTTPS - Subscription URLs must support SSL. Use RequestBin for testing if needed.
✅ Implement Redundancy - Webhooks may be delayed or lost. Use GET endpoints to periodically reconcile data.
✅ Retry Handling - Events may arrive out of order due to retries—handle them as independent updates.
✅ Use Idempotency - Store webhook event ids and discard duplicates to prevent redundant processing.
✅ Logging & Monitoring - Log webhook requests and responses to diagnose issues.
Yes, you can view webhook logs in the ShipBob dashboard by going to Integrations > Webhooks. Then, click into your webhook and you will be able to see logs at the bottom of the page.
![]()
returns a 2XX response to ShipBob’s POST request.has the correct webhooks_read or webhooks_write permissions.2XX response before doing heavy processing.