Guides
Receive webhooks
Register an endpoint, verify every delivery, respond fast and process later, and test it all from your laptop with the CLI.
Webhooks tell your backend when something happened without polling: a staff member replied, a job finished, a video is ready, credits are low. This guide takes an endpoint from registration to a handler you can trust.
1. Register an endpoint
In the developer console (Developers → Webhooks) add an https URL and pick the
events. The secret (whsec_…) is shown once, store it beside your API key as
DHANU_WEBHOOK_SECRET. The full event list with a payload example each is on
events.
2. Verify, acknowledge, then work
Verify the signature on the raw body before parsing anything, answer 2xx
within a few seconds, and do the real work afterwards. A slow handler is retried
as if it had failed, and a handler that trusts an unsigned body can be fed
anything by whoever guesses your URL.
import express from "express";
import { Dhanu, WebhookSignatureError, type DhanuWebhookEvent } from "dhanu";
const dhanu = new Dhanu(process.env.DHANU_API_KEY!);
const app = express();
app.post("/hooks/dhanu", express.raw({ type: "application/json" }), async (req, res) => {
let event: DhanuWebhookEvent;
try {
event = await dhanu.webhooks.verify(
req.body.toString("utf8"),
req.header("Dhanu-Signature"),
process.env.DHANU_WEBHOOK_SECRET!,
);
} catch (err) {
if (err instanceof WebhookSignatureError) return res.sendStatus(400);
throw err;
}
res.sendStatus(200);
await queue.add(event.type, event);
});from flask import Flask, request, abort
from dhanu import Dhanu, WebhookSignatureError
dhanu = Dhanu(os.environ["DHANU_API_KEY"])
app = Flask(__name__)
@app.post("/hooks/dhanu")
def hooks():
try:
event = dhanu.webhooks.verify(
request.get_data(as_text=True),
request.headers.get("Dhanu-Signature"),
os.environ["DHANU_WEBHOOK_SECRET"],
)
except WebhookSignatureError:
abort(400)
queue.enqueue(process, event)
return "", 200 3. Handle each event once
Deliveries can arrive twice, a retry after a timeout, a resend from the console.
Key your processing on event.id and skip one you have seen.
4. Test from your laptop
Dhanu delivers only to public https URLs, so during development point the endpoint at a tunnel or your staging server and let the CLI replay what it receives on your machine:
dhanu webhooks listen --endpoint <endpointId> --forward-to localhost:3000/hooks/dhanu --secret $DHANU_WEBHOOK_SECRET
dhanu trigger task.completed --endpoint <endpointId>
listen re-posts every new delivery to your local handler with a
Dhanu-Signature computed from the secret you pass, so the verification above
runs for real; trigger fires a test event of any type.
5. Rotate without downtime
Rotating the secret keeps the old one valid for 24 hours, and every delivery in
that window carries two v1 signatures. Deploy the new secret, then rotate.