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.


Webhook Authentication

Securing webhook endpoints is crucial to ensure data integrity and authenticity. EasyPost recommends two primary methods for securing webhooks:

HMAC Validation

HMAC validation ensures webhook data is untampered during transmission.

  • Include a webhook_secret when creating or updating a webhook.
  • EasyPost generates a signature with this secret, sent via the X-Hmac-Signature header 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

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.


TLS and Certificate Validation

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 object

id
string
Unique, begins with "hook_"
object
string
"Webhook"
mode
string
"test" or "production"
url
string
http://example.com
disabled_at
datetime
The timestamp at which the Webhook was most recently disabled (if any)
custom_headers
[]map[string]string
A list of key-value pairs, each containing "name" and "value" fields. If not specified during creation, this field defaults to an empty array [].
Webhook Object
{
  "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"
    }
  ]
}

Custom Outbound Headers

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.

Validation Requirements

  • Custom headers must be an array of key-value pairs.
  • Each name must be unique within the list.
  • If specified in a POST or PATCH request, both name and value are mandatory.
  • Headers prefixed with X-EasyPost-* cannot be used.
  • Existing X-* standard name or non-standard X-* headers may be overwritten if a conflict exists.
  • Header values are stored in plaintext. Use encrypted values if sensitive information is included.

Updating Custom Headers

Updating replaces the entire custom_headers list. Partial updates are not supported.

RFC Compliance

All custom header names must conform to RFC 7230/ RFC 9112 formatting rules.


Create a Webhook

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

url
i.e. "https://example.com"
This is the URL that your webhook will receive data at
webhook_secret
i.e. "A1B2C3"
The webhook secret to perform HMAC validation with used to secure a webhook
custom_headers
i.e. "X-Header-Name" and "header_value"
List of custom headers desired on outbound webhook requests.
POST /webhooks
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  }'
Response
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 all Webhooks

Retrieve an unpaginated list of all Webhooks associated with the API Key.

GET /webhooks
1curl -X GET https://api.easypost.com/v2/webhooks \
2  -u "EASYPOST_API_KEY":
Response
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

Retrieve a Webhook by id.

GET /webhooks/:id
1curl -X GET https://api.easypost.com/v2/webhooks/hook_... \
2  -u "EASYPOST_API_KEY":
Response
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}

Update a Webhook

Re-enable a disabled Webhook or update the webhook_secret and custom_headers.

Request Parameters

webhook_secret
i.e. "A1B2C3"
The webhook secret to perform HMAC validation with used to secure a webhook
custom_headers
i.e. "X-Header-Name" and "header_value"
List of optional custom headers to include with outbound webhook requests. Each entry must contain a "name" and "value".
PATCH /webhooks/:id
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  }'
Response
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

Delete a Webhook by id.

DELETE /webhooks/:id
1curl -X DELETE https://api.easypost.com/v2/webhooks/hook_... \
2  -u "EASYPOST_API_KEY":
Response
1{}