Webhooks
Webhooks let you subscribe to events on your PaperDB database. When an event fires, PaperDB sends an HTTP POST to your endpoint with a signed payload.
Creating a Webhook
curl -X POST https://api.paperdb.app/webhooks \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["document.created", "document.updated"],
"collections": ["users", "orders"],
"description": "Order notifications"
}'Supported Events
- document.created — a new document was inserted.
- document.updated — an existing document was patched.
- document.deleted — a document was deleted.
- * — wildcard, triggers on all events.
Verifying Signatures
Every delivery includes an X-PaperDB-Signature header — an HMAC SHA-256 hash of the raw request body using your webhook secret. Verify it before processing the payload.
The secret is shown once when you create the webhook. Use POST /webhooks/:id/rotate-secret to generate a new one. The secret is never returned in GET responses.
import { createHmac } from "crypto";
function verifyWebhook(
rawBody: string,
signature: string,
secret: string
): boolean {
const expected = "sha256=" + createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return signature === expected;
}
// In your Express/Hono handler:
app.post("/webhook", (req, res) => {
const sig = req.headers["x-paperdb-signature"] as string;
if (!verifyWebhook(req.rawBody, sig, process.env.WEBHOOK_SECRET!)) {
return res.status(401).send("Invalid signature");
}
// process payload...
res.sendStatus(200);
});Or use the SDK helper which does this for you:
import { createWebhookHandler } from "paperdb";
const handler = createWebhookHandler(process.env.WEBHOOK_SECRET!, (payload, event) => {
console.log("Event:", event, payload);
});Delivery & Retries
Deliveries are queuedand processed asynchronously. If your server returns a non-2xx status or times out (30 s), PaperDB retries with exponential backoff — up to 5 attempts. You can also retry manually from the dashboard or via the API.
Managing Webhooks via SDK
// Create
const hook = await db.webhooks.create({
url: "https://example.com/hook",
events: ["document.created", "document.deleted"],
collections: ["orders"]
});
// List / get
const hooks = await db.webhooks.list();
const hook = await db.webhooks.get(id);
// Update
await db.webhooks.update(id, { enabled: false });
// Send a test delivery
const delivery = await db.webhooks.test(id);
// View delivery history
const deliveries = await db.webhooks.getDeliveries(id);
// Retry a failed delivery
await db.webhooks.retryDelivery(id, deliveryId);
// Rotate secret
const { secret } = await db.webhooks.rotateSecret(id);
// Delete
await db.webhooks.delete(id);