Agent skill

Humaans Webhooks Skill

Receive and verify Humaans (HRIS) webhooks. Use when setting up a Humaans webhook handler, debugging Standard Webhooks / Svix signature verification (webhook-signature, whsec_ secret), or handling person.created, person.offboarded, timeAway.approved and compensation.updated events.

Install this skill

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


Humaans is an HR information system (HRIS). Its webhooks tell you when people, time away, compensation, job roles, bank accounts, emergency contacts and equipment change, so you can sync payroll, IT provisioning and directories without polling. Webhooks are created by an Owner and delivered through Svix.

When to Use This Skill

  • How do I receive Humaans webhooks?
  • How do I verify Humaans webhook signatures (webhook-signature, whsec_ secret)?
  • How do I handle person.created, person.offboarded or timeAway.approved events?
  • Where do I get the Humaans webhook signing secret?
  • Why is my Humaans webhook signature verification failing?

Verification (core)

Humaans deliveries follow Standard Webhooks: webhook-id, webhook-timestamp (Unix seconds) and webhook-signature (space-delimited v1,<base64> entries). Svix can send the same values as svix-id, svix-timestamp and svix-signature, so accept either prefix. The signature is base64 HMAC-SHA256 over {id}.{timestamp}.{raw body}, keyed with the base64-decoded part of the whsec_... secret.

Use the standardwebhooks library (Node and Python). It throws on a bad signature or a timestamp more than 5 minutes off, and returns the parsed payload:

const { Webhook } = require('standardwebhooks');   // Python: from standardwebhooks.webhooks import Webhook
const h = (name) => req.headers[`webhook-${name}`] ?? req.headers[`svix-${name}`];
const event = new Webhook(process.env.HUMAANS_WEBHOOK_SECRET).verify(rawBody, {
  'webhook-id': h('id'),
  'webhook-timestamp': h('timestamp'),
  'webhook-signature': h('signature'),
});

Verify against the raw body before parsing JSON (in Express use express.raw({ type: '*/*' }) so any content type is read raw).

Timestamp window and Hookdeck. The standardwebhooks and svix libraries always enforce a fixed 5-minute timestamp window, and it can't be turned off. Hookdeck retries and replays resend the original webhook-timestamp, so the library rejects them once they are more than 5 minutes old. If you receive through Hookdeck and need late retries and replays to pass, use the manual verifier in references/verification.md (HMAC-SHA256 over {id}.{timestamp}.{raw body}, key = base64-decoded secret after whsec_, every space-separated v1,<base64> entry compared in constant time), where the window can be dropped or widened.

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

Common Event Types

The body is an event wrapper (id, seq, ts, action, subject, actor, entity); dispatch on action.

Event (action)Sent when
person.createdA person is added
person.updatedA person's profile changes
person.offboardedA person is offboarded (person.reonboarded when they return)
timeAway.createdA time away request is created (also .updated, .deleted, .rejected)
timeAway.approvedA time away request is approved
compensation.updatedA compensation record changes (also .created, .deleted)

Other actions: person.deleted, timeAwayAdjustment.*, bankAccount.*, jobRole.*, emergencyContact.*, equipment.* (each created, updated, deleted). See references/overview.md.

Important Headers

HeaderDescription
webhook-id (or svix-id)Message ID; unchanged on retries, use it for idempotency
webhook-timestamp (or svix-timestamp)Unix seconds of this delivery attempt
webhook-signature (or svix-signature)v1,<base64> entries, space-delimited (several during secret rotation)

Environment Variables

HUMAANS_WEBHOOK_SECRET=whsec_xxxxx   # prodEndpointSignature of the webhook, e.g. whsec_vwbddlgH8lyKqHEDzn3EUpmk

Local Development

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

Use the printed URL as the webhook's production endpoint URL, then publish the webhook so Humaans starts delivering. Any 2xx response is a success; other responses are retried with exponential backoff.

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 6, 2026

View on GitHub →