Webhooks
Get notified when products, designs and projects change, and verify every delivery.
Overview
Webhook subscriptions notify your app when something changes in a store, so you do not have to poll the API. After you subscribe to a topic, Printcart sends an HTTP POST to your callback URL whenever a matching event occurs. Creating, listing and removing subscriptions is done with the /webhooks endpoints in the API reference.
Topics and events
One subscription covers one topic and one event.
| Topic | Resource |
|---|---|
products | Product |
sides | Side |
designs | Design |
templates | Template |
projects | Project (order) |
user | User |
Events: POST, PUT, DELETE, POST BATCH, PUT BATCH and DELETE BATCH.
The subscription object
| Property | Description |
|---|---|
id | Unique identifier of the subscription |
callback_url | Destination URL that receives the POST request when the event occurs |
topic | Topic of the subscription |
event | Event that triggers the webhook |
created_at | When the subscription was created |
updated_at | When the subscription was last updated |
Payload
The request body wraps the resource exactly as the API returned it for the triggering request. The outer data is added by the delivery job.
{
"data": {
"data": {
"id": "4419934f-8e1b-4cf0-b432-01ef9258a812",
"name": "project example",
"status": "processing",
"note": "project example note",
"created_at": "2021-11-16T08:26:30.000000Z",
"updated_at": "2021-11-16T08:26:30.000000Z"
},
"message": "Created successfully"
}
}Batch events carry a list of resources in the inner data. The shape of each resource matches the corresponding schema in the API reference.
Verify the signature
Every delivery carries a Signature header. Verify it before you trust the request.
- Header:
Signature - Algorithm: HMAC-SHA256 of the raw request body, hex encoded
- Key:
base64(sid:secret), the same string you put afterBasicin anAuthorizationheader
Compute the HMAC over the raw body, not over parsed JSON, and compare with a constant-time function.
import crypto from 'node:crypto'
export function isValidSignature(rawBody, signatureHeader, sid, secret) {
const key = Buffer.from(`${sid}:${secret}`).toString('base64')
const expected = crypto.createHmac('sha256', key).update(rawBody).digest('hex')
return (
expected.length === signatureHeader.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader))
)
}Keep the store sid and secret on your server and never publish them.
Delivery behaviour
- A failed delivery is retried up to 3 times with exponential backoff, and each attempt times out after 3 seconds. Respond quickly and process the event asynchronously.
- There is no delivery log and no replay endpoint. If your receiver was down, reconcile by listing the affected resources through the API.
- Webhooks are sent from the production environment only, so test your receiver against a production test store.