Webhooks API

Webhooks deliver real-time event notifications to your server.

Requires: Pro subscription

List webhooks

GET /brand/webhooks
Authorization: Bearer <token>
X-Organization-Id: <org_id>

Returns:

{
  "data": [
    {
      "id": "01KS...",
      "url": "https://example.com/webhooks/pasera",
      "events": ["dpp.published", "batch.submitted"],
      "active": true,
      "createdAt": 1716000000000
    }
  ]
}

Create webhook

POST /brand/webhooks
Authorization: Bearer <token>
X-Organization-Id: <org_id>
Content-Type: application/json
 
{
  "url": "https://example.com/webhooks/pasera",
  "events": ["dpp.published", "batch.submitted"]
}

Returns the created webhook including a secret field. Store this secret securely — it’s used to verify webhook signatures.

Delete webhook

DELETE /brand/webhooks/:id
Authorization: Bearer <token>
X-Organization-Id: <org_id>

Available events

EventFires when
batch.createdA new batch is created
batch.submittedA factory submits DPP data for a batch
dpp.publishedA DPP is approved and published
request.sentA DPP request is sent to a factory
certificate.expiringA supplier certificate expires within 30 days

Webhook delivery

Each webhook delivery includes:

Headers:

  • Content-Type: application/json
  • X-Pasera-Signature: <hmac-sha256-hex>
  • X-Pasera-Event: <event-name>
  • X-Pasera-Delivery: <delivery-id>

Body:

{
  "event": "dpp.published",
  "timestamp": "2026-05-15T10:30:00Z",
  "data": {
    "dppId": "01KS...",
    "batchId": "01KS...",
    "productName": "Classic Crew T-Shirt",
    "qrUrl": "https://p.pasera.app/p/5701234567001/ABC123"
  }
}

Signature verification

Verify that webhooks are genuinely from Pasera by checking the HMAC-SHA256 signature:

const crypto = require('crypto');
 
function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
 
// In your webhook handler:
app.post('/webhooks/pasera', (req, res) => {
  const sig = req.headers['x-pasera-signature'];
  if (!verifyWebhook(req.rawBody, sig, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  // Process the event...
  res.status(200).send('OK');
});

Retry policy

Failed deliveries (non-2xx response or timeout after 10 seconds) are retried up to 3 times with exponential backoff (1 min, 5 min, 30 min).