Agent skill
Pipedream Webhooks Skill
Receive and verify Pipedream Connect webhooks. Use when setting up a Pipedream Connect trigger webhook handler, verifying the x-pd-signature header (t=<timestamp>,v1=<hex>, HMAC-SHA256 over "<timestamp>.<raw body>"), debugging Pipedream signature verification failures, or handling the unsigned CONNECTION_SUCCESS and CONNECTION_ERROR connection webhooks sent to a Connect token's webhook_uri.
Install this skill
npx skills add hookdeck/webhook-skills --skill pipedream-webhooks
When to Use This Skill
- How do I receive Pipedream Connect trigger webhooks (events emitted by deployed triggers)?
- How do I verify the Pipedream
x-pd-signaturewebhook signature? - Why is my Pipedream webhook signature verification failing?
- How do I handle
CONNECTION_SUCCESS/CONNECTION_ERRORwhen an end user connects an account? - Where do I find the Pipedream webhook signing key?
Two kinds of Pipedream Connect webhooks
| Webhook | Sent to | Signed? |
|---|---|---|
| Trigger webhooks (events emitted by deployed triggers) | Trigger-level webhook_url, or the project-level webhook URL for the environment | Yes: x-pd-signature |
Connection webhooks (CONNECTION_SUCCESS, CONNECTION_ERROR) | The webhook_uri passed when creating a Connect token | Not documented as signed |
Caveat: Pipedream only documents Connect trigger webhooks as signed. Connection webhooks and plain workflow HTTP requests carry no documented signature, so
x-pd-signatureverification does not apply to them. Protect a connection webhook URL with a secret of your own (e.g. a random?token=inwebhook_uri) and confirm the account with the Retrieve Account API before trusting the payload.
Verification (core)
Trigger webhook deliveries carry:
x-pd-signature: t=1616000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
v1 is the HMAC-SHA256 hex digest of <t>.<raw body>, keyed with the signing key as a UTF-8 string. Compare in constant time and reject t more than 300 seconds old (Pipedream's replay guidance).
const crypto = require('crypto');
function verifyPipedreamSignature(rawBody, header, signingKey, toleranceSeconds = 300) {
if (!header) return false;
const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split(/=(.*)/s, 2)));
const { t, v1 } = parts;
if (!/^[0-9]+$/.test(t || '') || !v1) return false;
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSeconds) return false; // replay
const expected = crypto.createHmac('sha256', signingKey)
.update(`${t}.`).update(rawBody) // raw bytes, never re-serialised JSON
.digest('hex');
return v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(v1.toLowerCase()), Buffer.from(expected));
}
Python: hmac.new(key.encode(), f"{t}.".encode() + raw_ compared with hmac.compare_digest.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Pipedream has no SDK helper for webhook verification (@pipedream/sdk only manages webhooks and signing keys), so every example verifies manually.
Common Event Types
| Event | Webhook | Description |
|---|---|---|
CONNECTION_SUCCESS | Connection (unsigned) | End user connected an account. account.id (apn_…) and account.external_id are in the body; credentials are not, so fetch them with Retrieve Account |
CONNECTION_ERROR | Connection (unsigned) | The connect flow failed; error holds the message |
| Trigger event | Trigger (signed) | Whatever the deployed trigger emitted (e.g. a GitLab issue from gitlab-new-issue). There is no Pipedream-level event type field, so route on which trigger/URL it came from |
See references/overview.md for payloads.
Environment Variables
PIPEDREAM_WEBHOOK_SIGNING_KEY=your_pipedream_signing_key # Trigger webhooks; shown once when the URL is saved
PIPEDREAM_CONNECT_WEBHOOK_TOKEN=random_string # Optional; checked against ?token= on connection webhooks
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 pipedream --path /webhooks/pipedream
Set the printed URL as the project webhook URL (or a trigger's webhook_url), copy the signing key, and deploy a trigger.
Reference Materials
- references/overview.md - Trigger vs connection webhooks, payloads, events
- references/setup.md - Project-level and trigger-level webhook URLs, signing keys, Connect tokens
- references/verification.md - Header format, algorithm, replay window, gotchas