Webhooks
Subscribe to signed outbound webhooks for scan.completed and credits.low, and verify the signature before trusting a delivery.
Webhooks push events to your systems so you don’t have to poll. Create a subscription with a delivery URL, and AskThis sends a signed POST whenever a subscribed event fires.
You can manage subscriptions two ways: in the dashboard under Developers (create, pause, send a test, delete — the signing secret is shown once at creation), or over the API as shown below.
Events
| Event | Fires when |
|---|---|
scan.completed |
An onboarding or re-scan finishes and prompts are ready |
scan.failed |
A scan job errors out |
credits.low |
Your credit balance drops below the low-balance threshold |
credits.depleted |
Your credit balance hits zero — act now (top up or upgrade) |
citation.detected |
A Citation Monitor run finds your site cited by an AI engine |
subscription.updated |
Your plan changes — created, upgraded, downgraded or cancelled |
invoice.paid |
A gateway invoice is paid |
site.installed |
A site’s widget is verified live for the first time |
Subscribe to any subset. Subscribing to an event name outside this list is rejected with a 422.
Example payloads
// credits.depleted
{ "event": "credits.depleted", "payload": { "orgId": "org_...", "balance": 0 },
"timestamp": "2026-07-15T09:00:00.000Z" }
// citation.detected
{ "event": "citation.detected",
"payload": { "siteId": "cq_8f2a", "cited": 3, "total": 6, "engines": ["chatgpt", "gemini"] },
"timestamp": "2026-07-15T09:00:00.000Z" }
// subscription.updated
{ "event": "subscription.updated",
"payload": { "orgId": "org_...", "plan": "business", "status": "active", "cancelled": false },
"timestamp": "2026-07-15T09:00:00.000Z" }
Subscribing
# Create a subscription → the signing secret is returned ONCE
curl -X POST https://api.askthis.io/api/v1/webhook-subscriptions \
-H "Authorization: Bearer <session>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.yoursite.com/askthis",
"events": ["scan.completed", "credits.low"]
}'
# List subscriptions (the secret is never shown again)
curl https://api.askthis.io/api/v1/webhook-subscriptions -H "Authorization: Bearer <session>"
# Delete a subscription
curl -X DELETE https://api.askthis.io/api/v1/webhook-subscriptions/<id> \
-H "Authorization: Bearer <session>"
Verifying deliveries
Every delivery is signed with HMAC-SHA256 over the raw request body, using your subscription secret. The hex signature arrives in the X-AskThis-Signature header. Recompute it and compare before trusting the payload:
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(header ?? "");
return a.length === b.length && timingSafeEqual(a, b);
}
// Express example (raw body required)
app.post("/askthis", express.raw({ type: "application/json" }), (req, res) => {
if (!verify(req.body, req.get("X-AskThis-Signature"), process.env.ASKTHIS_WEBHOOK_SECRET)) {
return res.status(401).end();
}
const event = JSON.parse(req.body.toString());
// handle event.type: "scan.completed" | "credits.low"
res.status(200).end();
});
Test & debug
Verify a subscription without waiting for a real event — send a sample signed ping:
curl -X POST https://api.askthis.io/api/v1/webhook-subscriptions/<id>/test \
-H "Authorization: Bearer <session>"
# → { "data": { "delivered": true, "status": "200" }, ... }
And inspect the recent delivery attempts (newest first) to debug failures:
curl https://api.askthis.io/api/v1/webhook-subscriptions/<id>/deliveries \
-H "Authorization: Bearer <session>"
# → [{ "event": "scan.completed", "status": "200", "at": "..." }, ...]
Delivery guarantees
- Signed — always verify the signature; reject on mismatch.
- Time-boxed — each delivery attempt times out after 5 seconds, so respond fast (queue the work, return
200). - Retried — failed deliveries are retried, so make your handler idempotent (dedupe on the event ID).
See also: API keys for authenticating the management calls above.