API cookbook
Subscribe to pricing.computed events
Create a webhook subscription, verify deliveries, and idempotently consume events on your side.
intermediateTypeScript · Node.js
1. Create the subscription
POST /v1/webhooks
{
"targetUrl": "https://yourapp.example.com/webhooks/ratestack",
"eventTypes": ["pricing.computed"]
}
# 201 Created
{
"id": "wh_C1c8a4ed",
"targetUrl": "https://yourapp.example.com/webhooks/ratestack",
"eventTypes": ["pricing.computed"],
"secret": "whsec_8R2K3J7M..." ← only shown once. Store immediately.
}2. Verify on receive
import express from "express";
import crypto from "node:crypto";
const app = express();
const SECRET = process.env.RATESTACK_WEBHOOK_SECRET!;
app.post(
"/webhooks/ratestack",
express.text({ type: "*/*" }),
async (req, res) => {
const sig = (req.header("x-ratestack-signature") ?? "").replace(/^sha256=/, "");
const ts = Number(req.header("x-ratestack-timestamp") ?? "0");
const eventId = req.header("x-ratestack-event-id") ?? "";
if (!Number.isFinite(ts) || Math.abs(Date.now() / 1000 - ts) > 300) {
return res.status(400).end();
}
const expected = crypto
.createHmac("sha256", SECRET)
.update(`${ts}.${req.body}`)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
return res.status(400).end();
}
// Idempotency — dedupe by eventId
if (await alreadyProcessed(eventId)) return res.status(200).end();
await markProcessed(eventId);
const body = JSON.parse(req.body) as { type: string; data: unknown };
await enqueue(body);
res.status(200).end();
},
);Critical points: ack 200 on duplicate (don't 5xx); enqueue rather than process inline; honor the 30-second timeout.