Agent skill

FullEnrich Webhooks Skill

Receive and verify FullEnrich webhooks. Use when setting up a FullEnrich webhook_url or webhook_events.contact_finished callback, verifying the X-Signature-SHA1 header (HMAC-SHA1 hex keyed with your FullEnrich API key), debugging signature verification failures, or handling enrichment results with status FINISHED, IN_PROGRESS, CANCELED, or CREDITS_INSUFFICIENT.

Install this skill

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


When to Use This Skill

  • How do I receive FullEnrich webhooks for enrichment or reverse email lookup results?
  • How do I verify the FullEnrich X-Signature-SHA1 webhook header?
  • Which secret signs FullEnrich webhooks? (Your FullEnrich API key; there is no separate webhook secret.)
  • How do I handle each contact as it completes (webhook_events.contact_finished) versus the finished batch (webhook_url)?
  • Why is my FullEnrich webhook signature verification failing?

Verification (core)

FullEnrich sends X-Signature-SHA1: the lowercase hex HMAC-SHA1 of the raw request body, keyed with your FullEnrich API key. The algorithm is SHA-1, not SHA-256. There is no timestamp and no prefix. Verify against the raw bytes before parsing JSON.

const crypto = require('crypto');

function verifyFullEnrichSignature(rawBody, signature, apiKey) {
  // Check shape first: Buffer.from(x, 'hex') silently truncates invalid hex
  if (!signature || !apiKey || !/^[0-9a-f]{40}$/i.test(signature)) return false;
  const expected = crypto.createHmac('sha1', apiKey).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature.toLowerCase()));
}
def verify_fullenrich_signature(raw_body: bytes, signature: str | None, api_key: str) -> bool:
    expected = hmac.new(api_key.encode(), raw_body, hashlib.sha1).hexdigest()
    # Encode both sides: compare_digest raises TypeError on non-ASCII str
    return hmac.compare_digest(expected.encode(), (signature or "").lower().encode())

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

Hookdeck Setup

FullEnrich signs webhooks with your FullEnrich API key. In Hookdeck, create a FullEnrich source and paste that key as the signing secret. See references/setup.md.

Payloads and Statuses

FullEnrich has no event types. Each webhook is a per-request callback whose body mirrors the Get Enrichment Result response. Branch on the status field (the job state):

statusDelivered viaMeaning
FINISHEDwebhook_urlThe whole batch completed
CANCELEDwebhook_urlThe batch was canceled
CREDITS_INSUFFICIENTwebhook_urlThe batch ran out of credits
IN_PROGRESSwebhook_events.contact_finishedOne contact finished; the batch is still running (single contact in data)

CREATED also exists as a job state but is not documented as a webhook status. Pass a custom object (string values) on each input to correlate results with your own IDs. See references/overview.md.

Important Headers

HeaderDescription
X-Signature-SHA1Lowercase hex HMAC-SHA1 of the raw body, keyed with your API key

Environment Variables

FULLENRICH_API_KEY=your_fullenrich_api_key   # app.fullenrich.com/app/api

Local Development

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

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 9, 2026

View on GitHub →