Quick answer
Register an endpoint in Admin → Settings → Developer & API, choose the events
you want, and ASHR sends a signed POST when they happen. Verify the
X-Demystify-Signature header with the secret (shown once) so you can
trust the payload.
The payload
{ "event": "leave.created", "created": 1725448800, "data": { "id": "…", "employee_id": "…" } }
Headers: X-Demystify-Event: leave.created and
X-Demystify-Signature: t=1725448800,v1=<hex>.
Verify the signature
The signed string is `${t}.${rawBody}` and the signature is HMAC-SHA256 of
it with your endpoint secret. Recompute and compare in constant time; reject if
it doesn't match or t is more than a few minutes old.
import crypto from 'node:crypto'
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex')
const ok = crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(parts.v1, 'hex'))
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300
return ok && fresh
}
Return a 2xx fast and process asynchronously; treat delivery as at-least-once, so make your handler idempotent.
Frequently asked questions
- Which events can I subscribe to?
- Today — leave.created, leave.approved, leave.rejected and leave.cancelled. Pick specific events or subscribe to everything.
- How do I know a webhook really came from ASHR?
- Every request carries X-Demystify-Signature — an HMAC-SHA256 of "<timestamp>.<rawBody>" using your endpoint secret. Recompute it and compare; reject if it doesn't match or the timestamp is too old.
- What if my endpoint is down?
- Delivery is best-effort and each attempt is recorded. Build your handler to be idempotent (the same event may arrive more than once) and return a 2xx quickly.
Related articles
How do I use the ASHR.work API?
Create an API key with the scopes you need, send it as a Bearer token to /api/v1, and read or write your workspace data — with cursor pagination, idempotent writes and RFC 9457 errors.
How do I create API keys and use OAuth2?
Generate scoped API keys (shown once, hashed at rest), edit, rotate or revoke them; or register an OAuth2 client to exchange a client id + secret for short-lived access tokens with refresh.