Agent skill
dbt Cloud Webhooks Skill
Receive and verify dbt Cloud webhooks. Use when setting up dbt Cloud webhook handlers, debugging dbt Cloud Authorization header signature verification, or handling job run events like job.run.started, job.run.completed, and job.run.errored.
Install this skill
npx skills add hookdeck/webhook-skills --skill dbt-cloud-webhooks
When to Use This Skill
- How do I receive dbt Cloud webhooks?
- How do I verify dbt Cloud webhook signatures?
- How do I handle
job.run.completedorjob.run.erroredevents? - Why is my dbt Cloud webhook signature verification failing?
- Why am I getting two notifications for one failed dbt Cloud run?
Verification (core)
dbt Cloud has no Signature header and no scheme prefix. The Authorization header carries the bare lowercase hex HMAC-SHA256 of the raw request body, keyed with the webhook's secret (hmac_secret in the API, shown once in the UI when you save the webhook). Use the secret as a raw UTF-8 string and the raw body (don't JSON.parse first). There is no timestamp, so dedupe on eventId.
const crypto = require('crypto');
function verifyDbtCloudSignature(rawBody, authHeader, secret) {
if (!authHeader) return false;
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(authHeader.trim());
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
For complete handlers with route wiring, event dispatch, and tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
| Event | Triggered When |
|---|---|
job.run.started | A job run starts |
job.run.completed | A run finishes, succeeded or failed (fires after metadata and artifacts are ingested) |
job.run.errored | A run errors (fires immediately; artifacts may not be available yet) |
job.run.errored is a subset of job.run.completed: subscribe to both and an errored run notifies you twice.
For the full event reference, see references/overview.md and dbt's webhook documentation.
Environment Variables
# hmac_secret returned when the webhook is created (raw string, no decoding)
DBT_CLOUD_WEBHOOK_SECRET=your_dbt_cloud_webhook_secret_here
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 dbt-cloud --path /webhooks/dbt-cloud
Reference Materials
- references/overview.md - What dbt Cloud webhooks are, events, payload fields
- references/setup.md - Creating a webhook in the UI or API, getting the secret
- references/verification.md - Signature verification details and gotchas