Webhook
Each Webhook contains the url that EasyPost notifies when an object in the system updates.
Several types of objects are processed asynchronously within EasyPost. When an object updates, an Event is sent via HTTP POST to each configured
webhook url. The webhook object supports create, retrieve, update, and delete (CRUD) operations.
For best practices and request sanitation, refer to the Webhooks Guide.
Webhook endpoints must return a 2XX status code to indicate successful receipt. A 200 OK response is preferred. Endpoints that repeatedly return failures may be
automatically disabled; disabled webhooks can be re-enabled using the Webhook update endpoint.
Securing webhook endpoints is crucial to ensure data integrity and authenticity. EasyPost recommends two primary methods for securing webhooks:
HMAC validation ensures webhook data is untampered during transmission.
- Include a
webhook_secretwhen creating or updating a webhook. - EasyPost generates a signature with this secret, sent via the
X-Hmac-Signatureheader in each event. - Validate the signature using
validate_webhook()from EasyPost’s client libraries (function name may vary depending on the programming language; refer to the library documentation). - If the signature does not match, reject the event to prevent fraudulent data.
Basic authentication requires embedding a username and password in the webhook URL.
Example
https://username:secret@example.com/easypost-webhook
Each webhook delivery includes an Authorization header. Validate the credentials against the stored values.
EasyPost performs certificate validation and requires that any webhook recipient using TLS (HTTPS) must have a certificate signed by a trusted public certification authority. This helps ensure that the data being transmitted is secure.
- Webhook endpoints must use
HTTPS. - SSLv2, SSLv3, and export-grade ciphers are not supported.
For server setup guidance, refer to:
Webhook was most recently disabled (if any){
"id": "hook_d31edbc62d1511f0a15761d2f710980c",
"object": "Webhook",
"mode": "test",
"url": "http://example.com",
"created_at": "2025-05-09T20:40:21Z",
"disabled_at": null,
"custom_headers": [
{
"name": "X-Header-Name",
"value": "header_value"
}
]
}EasyPost supports optional custom headers on outbound webhook requests, allowing up to three custom headers. Each header must include a name and
value, both as ASCII strings under 1000 characters.
- Custom headers must be an array of key-value pairs.
- Each
namemust be unique within the list. - If specified in a
POSTorPATCHrequest, bothnameandvalueare mandatory. - Headers prefixed with
X-EasyPost-*cannot be used. - Existing
X-*standard name or non-standardX-*headers may be overwritten if a conflict exists. - Header values are stored in plaintext. Use encrypted values if sensitive information is included.
Updating replaces the entire custom_headers list. Partial updates are not supported.
All custom header names must conform to RFC 7230/ RFC 9112 formatting rules.
To create a Webhook, provide a url parameter to designate where notifications are sent. A webhook can be secured using a webhook_secret for HMAC validation or basic authentication. The optional custom_headers attribute enables the inclusion of additional header information, such as authentication tokens or metadata, with outbound webhook requests.
Request Parameters
1curl -X POST https://api.easypost.com/v2/webhooks \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "webhook": {
6 "url": "example.com",
7 "webhook_secret": "A1B2C3",
8 "custom_headers": [{
9 "name": "X-Header-Name",
10 "value": "header_value"
11 }],
12 }
13 }'1{
2 "id": "hook_d31edbc62d1511f0a15761d2f710980c",
3 "object": "Webhook",
4 "mode": "test",
5 "url": "http://example.com",
6 "created_at": "2025-05-09T20:40:21Z",
7 "disabled_at": null,
8 "custom_headers": [
9 {
10 "name": "X-Header-Name",
11 "value": "header_value"
12 }
13 ]
14}Retrieve an unpaginated list of all Webhooks associated with the API Key.
1curl -X GET https://api.easypost.com/v2/webhooks \
2 -u "EASYPOST_API_KEY":1{
2 "webhooks": [
3 {
4 "id": "hook_d393bda62d1511f09d140fc7cf06773a",
5 "object": "Webhook",
6 "mode": "test",
7 "url": "http://example.com",
8 "created_at": "2025-05-09T20:40:22Z",
9 "disabled_at": null,
10 "custom_headers": [
11 {
12 "name": "X-Header-Name",
13 "value": "header_value"
14 }
15 ]
16 }
17 ]
18}Retrieve a Webhook by id.
1curl -X GET https://api.easypost.com/v2/webhooks/hook_... \
2 -u "EASYPOST_API_KEY":1{
2 "id": "hook_d34edeb62d1511f0b31155abe820005a",
3 "object": "Webhook",
4 "mode": "test",
5 "url": "http://example.com",
6 "created_at": "2025-05-09T20:40:21Z",
7 "disabled_at": null,
8 "custom_headers": [
9 {
10 "name": "X-Header-Name",
11 "value": "header_value"
12 }
13 ]
14}Re-enable a disabled Webhook or update the webhook_secret and custom_headers.
Request Parameters
1curl -X PATCH https://api.easypost.com/v2/webhooks/hook_... \
2 -u "EASYPOST_API_KEY": \
3 -H 'Content-Type: application/json' \
4 -d '{
5 "webhook_secret": "A1B2C3",
6 "custom_headers": [{
7 "name": "X-Header-Name",
8 "value": "header_value"
9 }],
10 }'1{
2 "id": "hook_d3d8d0ee2d1511f08c9a6175d1cdccad",
3 "object": "Webhook",
4 "mode": "test",
5 "url": "http://example.com",
6 "created_at": "2025-05-09T20:40:22Z",
7 "disabled_at": null,
8 "custom_headers": [
9 {
10 "name": "X-Header-Name",
11 "value": "header_value"
12 }
13 ]
14}Delete a Webhook by id.
1curl -X DELETE https://api.easypost.com/v2/webhooks/hook_... \
2 -u "EASYPOST_API_KEY":1{}