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

NameTypeDescription
idstringA unique ID prefixed with webhook_
objectstringAlways webhook
livebooleantrue if this is a live mode webhook else false
urlstringThe trigger URL of the webhook. Must be HTTPS
descriptionstring or nullOptional line describing this webhook
secretstringThe secret that the webhook JWT is signed with
enabledEventsstring arrayAll the event types that this webhook receives
payloadFormatstringEither jwt or json
enabledbooleanWhether this webhook is enabled or not
metadataobject or nullSee metadata

Webhook Notification

Once you verify the JWT PostGrid sends, this is what you will receive.

NameTypeDescription
typeWebhook Event TypeThe event type of the webhook
dataOrderThe complete order object associated with this event (letter, postcard, or cheque)

Webhook Invocation

NameTypeDescription
idstringA unique ID prefixed with webhook_invocation_
objectstringAlways webhook_invocation
webhookstringThe webhook ID which was invoked
typeWebhook Event TypeThe event type
statusCodenumberThe response from the invocation
orderIDstring or nullThe relevant order ID for the event

Webhook Event Types

NameDescription
letter.createdTriggered when a letter is created
letter.updatedTriggered when a letter object is updated
postcard.createdTriggered when a postcard is created
postcard.updatedTriggered when a postcard object is updated
cheque.createdTriggered when a cheque is created
cheque.updatedTriggered when a cheque object is updated
return_envelope_order.createdTriggered when a return envelope order is created
return_envelope_order.updatedTriggered when a return envelope order is updated
tracker.visitedTriggered when a tracker is visited