Webhooks
In this guide, we will look at how to register and consume webhooks to integrate your app with Punt Uit. With webhooks, your app can know when something happens in Punt Uit, such as shipping or receiving products or tracking the status of an outbound.
Registering webhooks
To subscribe to a webhook, you need to have a URL in your app that Punt Uit can call. You can use the Punt Uit API to create a new subscription.
Registering a new webhook
curl
--location
--request POST 'https://partner.punt-uit.nl/api/fulfilment/v3/subscriptions'
--header 'Authorization: Bearer ey...'
--header 'Content-Type: application/json'
--data-raw {
"notificationUrl": https://<yourdomain>.com/logger,
"event": "shipment-shipped"
}
Now, whenever something of interest happens in your app, a webhook is fired off by Punt Uit. In the next section, we'll look at how to consume webhooks.
Consuming webhooks
When your app receives a webhook request from Punt Uit, check the type
attribute to see what event caused it. The first part of the event type will tell you the payload type, e.g., a order, shipment, etc.
Example webhook payload
{
"type": "shipped",
"resource": "shipment",
"identifier": "1a2d1c669b0811ed840606955cf36fa4"
}
In the example above, a shipment was sent, the payload type is a sent
and the resource is a shipment
.
Event types
- Name
outbound-status
- Type
- Description
The status of an outbound has changed.
- Name
shipment-shipped
- Type
- Description
We shipped items for an outbound.
- Name
receipt-received
- Type
- Description
Products received for an inbound.
- Name
inbound-status
- Type
- Description
The status of an inbound has changed.
- Name
label-status
- Type
- Description
The status of a shipment for a label has changed.
This are the shipments associated with shipping labels, the shipments for an outbound do not have a status trigger.
Retries
When handling the webhook please accept the message and return 200 as quick as possible. Not after processing. When we do not get a 200 return in <timeout> the message will be retried in the following way: By default, we will retry sending the event for 24 hours and up to 185 times with an exponential back off and jitter , or randomized delay. If an event isn't delivered after all retry attempts are exhausted, the event is dropped.
Idempotency
We strongly advice using idempotency in your code. Using idempotency in API webhooks can bring several benefits, such as:
- It allows for retries: If a webhook fails, the system can retry it later without any negative consequences, as the same request will produce the same outcome.
- It increases robustness: Because the same request can be safely retried, the system is less likely to get into an inconsistent state if a webhook fails.
- It allows for deduplication: If a webhook is triggered multiple times due to a bug or network error, the duplicated requests can be safely ignored, as they will have the same effect as a single request.
- It eliminates the need to check if the same request had already been processed.
In summary, using idempotency in API webhooks improves reliability by allowing for retries and deduplication, and reduces complexity by eliminating the need to check for duplicates.
Security
To know for sure that a webhook was, in fact, sent by Punt Uit instead of a malicious actor, you can verify the request signature. Each webhook request contains a header named x-hook-signature
, and you can verify this signature by using your secret webhook key. The signature is an HMAC hash of the request payload hashed using your secret key. Here is an example of how to verify the signature in your app:
Verifying a request
const CryptoJS = require('crypto-js');
const generateHash = (payload, secret) => {
const hash = CryptoJS.HmacSHA256(payload, secret);
return CryptoJS.enc.Base64.stringify(hash);
}
...
const theirSignature = event.headers['x-hook-signature'];
const expectedSignature = generateHash(JSON.stringify(event.body), <yourwebhooksecret>);
if (theirSignature !== expectedSignature) {
console.error('unauthorized api call. x-hook-signature does not match.');
}
If your generated signature matches the x-hook-signature
header, you can be sure that the request was truly coming from Punt Uit. It's essential to keep your secret webhook key safe — otherwise, you can no longer be sure that a given webhook was sent by Punt Uit.