Agent skill

Workable Webhooks Skill

Receive and verify Workable webhooks. Use when setting up Workable webhook handlers, debugging X-Workable-Signature verification, or handling recruiting events like candidate_created, candidate_moved, employee_created, employee_updated, or employee_published.

Install this skill

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


When to Use This Skill

  • How do I receive Workable webhooks?
  • How do I verify the X-Workable-Signature header?
  • What key signs Workable webhooks (there is no webhook secret)?
  • How do I handle candidate_created or candidate_moved events?
  • Why is my Workable webhook signature verification failing?

Verification (core)

Workable signs the raw request body with HMAC-SHA256 and sends the digest in X-Workable-Signature. The key is not a dedicated webhook secret: it is the account API token that created the subscription, or the OAuth application secret for OAuth apps, used as a plain string.

Workable's docs don't state the digest encoding. Lowercase hex is what the maintained n8n and Botpress integrations use, and what these examples use. If your deliveries never match, compare against the base64 digest too.

Node:

const crypto = require('crypto');

function verify(rawBody, signatureHeader, key) {
  if (!signatureHeader) return false;
  const expected = crypto.createHmac('sha256', key).update(rawBody).digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(signatureHeader.toLowerCase()), Buffer.from(expected));
  } catch {
    return false;
  }
}

Python:

import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, key: str) -> bool:
    expected = hmac.new(key.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest((signature_header or "").lower().encode(), expected.encode())

Read the raw body regardless of content type (Express: express.raw({ type: '*/*' })). There is no timestamp header, so make handlers idempotent.

For complete handlers with route wiring, event dispatch, and tests, see:

Common Event Types

EventDescription
candidate_createdA candidate was added to a job
candidate_movedA candidate moved to another pipeline stage
employee_createdAn employee record was created
employee_updatedAn employee record was updated
employee_publishedAn employee record was published

Workable also documents candidate_deleted, job_deleted, onboarding_completed and timeoff_updated. See references/overview.md.

Important Headers

HeaderDescription
X-Workable-SignatureHMAC-SHA256 of the raw body (hex), keyed with the API token or OAuth app secret

Environment Variables

WORKABLE_SIGNING_KEY=your_api_token_or_oauth_app_secret   # The token that created the subscription

Local Development

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

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 4, 2026

View on GitHub →