Create and manage webhooks. Webhooks can be used to notify your application when events occur in PostGrid. For example, you may use a letter.updated
webhook to receive a notification when a letter has been processed for delivery.
Webhook payloads can be delivered in two formats, JSON Web Token (JWT) and JSON. The payload format of the webhook can be selected during creation, or updated accordingly afterwards. Note that updating a webhook's payload format will only affect future webhook invocations. By default, created webhooks will use the JWT payload format. Both formats require a webhook secret
, which is required to either decode or validate the payload respectively.
You must respond with a 200
status from your webhook. Otherwise, PostGrid will retry the webhook up to 3 times. First, after 1 hour, then 2 hours, then 4 hours. We will also keep track of every invocation and its response status. You can retrieve data about prior invocations using the webhook invocations list endpoint below.
JWT Payloads
When you receive an event with a JWT payload, you can verify it using a JWT library available for your particular language (using the HMAC SHA256 Algorithm). There are many off-the-shelf solutions you can use.
JSON Payloads
For JSON payloads, the data associated with the event is delivered in JSON, but the origin of the data must be verified. To verify that this webhook invocation originated from PostGrid, the webhook event is signed using the webhook secret, event payload, as well as a timestamp, and the signature is sent in the request headers of the invocation.
Verifying JSON Payloads
1. Extract the timestamp and signature from the request headers
Timestamp and signature is stored within the PostGrid-Signature
header in the following format:
PostGrid-Signature:t=1702916956,v1=j13wxqj8rtm8ce869dky52x2fk1d32z3x21q4f1kp63k81qkd0pgbm8hkeyw5thh
Where the characters following t=
in t=1702916956
represents the timestamp of the invocation, and the characters following v1
in v1=j13wxqj8rtm8ce869dky52x2fk1d32z3x21q4f1kp63k81qkd0pgbm8hkeyw5thh
is the signature.
2. Create the signed payload string
The webhook is signed by concatenating the following:
- The timestamp extracted in step 1
- The character
.
- The JSON payload passed in the request body
3. Compute the expected signature and compare it with the received signature
Using the signed payload string from step 2, calculate an Hash-based message authentication code (HMAC) using the SHA256 algorithm. The calculated signature should match the signature extracted from step 1.
Webhook Response
Name | Type | Description |
---|---|---|
id | string | A unique ID prefixed with webhook_ |
object | string | Always webhook |
live | boolean | true if this is a live mode webhook else false |
url | string | The trigger URL of the webhook. Must be HTTPS |
description | string or null | Optional line describing this webhook |
secret | string | The secret that the webhook JWT is signed with |
enabledEvents | string array | All the event types that this webhook receives |
payloadFormat | string | Either jwt or json |
enabled | boolean | Whether this webhook is enabled or not |
metadata | object or null | See metadata |
Webhook Notification
Once you verify the JWT PostGrid sends, this is what you will receive.
Name | Type | Description |
---|---|---|
type | Webhook Event Type | The event type of the webhook |
data | Order | The complete order object associated with this event (letter, postcard, or cheque) |
Webhook Invocation
Name | Type | Description |
---|---|---|
id | string | A unique ID prefixed with webhook_invocation_ |
object | string | Always webhook_invocation |
webhook | string | The webhook ID which was invoked |
type | Webhook Event Type | The event type |
statusCode | number | The response from the invocation |
orderID | string or null | The relevant order ID for the event |
Webhook Event Types
Name | Description |
---|---|
letter.created | Triggered when a letter is created |
letter.updated | Triggered when a letter object is updated |
postcard.created | Triggered when a postcard is created |
postcard.updated | Triggered when a postcard object is updated |
cheque.created | Triggered when a cheque is created |
cheque.updated | Triggered when a cheque object is updated |
return_envelope_order.created | Triggered when a return envelope order is created |
return_envelope_order.updated | Triggered when a return envelope order is updated |
tracker.visited | Triggered when a tracker is visited |