Agent skill

Outreach Webhooks Skill

Receive and verify Outreach webhooks. Use when setting up Outreach webhook handlers, creating a webhook with a secret, debugging Outreach-Webhook-Signature verification, or handling prospect.created, sequenceState.created, call.created and task.completed events.

Install this skill

npx skills add hookdeck/webhook-skills --skill outreach-webhooks


When to Use This Skill

  • How do I receive Outreach webhooks?
  • How do I verify the Outreach-Webhook-Signature header?
  • Why does my Outreach webhook have no signature header?
  • How do I handle prospect.created, sequenceState.created or call.created events?
  • Why is my Outreach webhook signature verification failing?

Set a Secret or Nothing Is Signed

Outreach signs a delivery only if the webhook has a secret attribute. Without one there is no Outreach-Webhook-Signature header, and a verifier (including Hookdeck's Outreach source) has nothing to check and rejects every request. Outreach's docs create webhooks through the API (POST /api/v2/webhooks), so include secret in the create request (or PATCH it onto an existing webhook). See references/setup.md.

The signature is the bare lowercase hex HMAC-SHA256 of the raw request body, keyed with the secret. There is no timestamp, no prefix, and no base64.

Verification (core)

const crypto = require('crypto');

function verifyOutreachSignature(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const received = Buffer.from(signatureHeader.trim().toLowerCase());
  const expectedBuf = Buffer.from(expected);
  // timingSafeEqual throws on length mismatch, so check length first
  return received.length === expectedBuf.length && crypto.timingSafeEqual(received, expectedBuf);
}
// rawBody: Buffer from express.raw({ type: '*/*' }); header: Outreach-Webhook-Signature
import hashlib, hmac

def verify_outreach_signature(raw_body: bytes, signature_header, secret) -> bool:
    if not signature_header or not secret:
        return False
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature_header.strip().lower().encode(), expected.encode())

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Read the body with express.raw({ type: '*/*' }) so any content type (the payload is JSON:API-styled, so it may arrive as application/vnd.api+json) reaches the verifier as unparsed bytes.

Common Event Types

meta.eventName is resource.action. Resources include account, call, emailAddress, mailing, opportunity, opportunityProspectRole, prospect, sequence, sequenceState, task, user, import and kaiaRecording.

EventTriggered When
prospect.createdA prospect is created
prospect.updatedA prospect changes
sequenceState.createdA prospect is added to a sequence
sequenceState.finishedA prospect finishes a sequence
call.createdA call is logged
task.completedA task is completed
mailing.repliedA prospect replies to an email

The payload is JSON:API: data (type, id, attributes, relationships) and meta (deliveredAt, eventName). Create and update events carry only the changed attributes. See references/overview.md.

Important Details

HeaderDescription
Outreach-Webhook-SignatureHex HMAC-SHA256 of the raw body (only present when a secret is set)
outreach-webhook-cleanup-tokenToken for removing the webhook through POST /api/v2/webhooks/cleanup
  • Respond 200 within 5 seconds. Outreach does not retry on any HTTP status (including 500 and 429); it retries only network failures (4 attempts, 1 second apart). Hand off slow work to a queue.
  • Redirects are not followed.
  • Outreach publishes no fixed IP list, so the signature is your authentication.

Environment Variables

OUTREACH_WEBHOOK_SECRET=your_webhook_secret   # the secret you set on the webhook via the API

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 outreach --path /webhooks/outreach

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 5, 2026

View on GitHub →