Integrations
Three ways in and out: a key another system uses to call us, a webhook we use to call it, and a terminal on a wall that does the first of those on its own. All three are configured in Settings → Integrations, and every one of them is scoped to the company that made it.
What you can connect
Doors and clocks
- Attendance terminalcalls us
- A fingerprint, face or card reader by the door. It uploads punches; the register fills in by itself.
Money
- Payroll bureau or accountingboth ways
- Where the month’s pay goes when somebody else runs it. A key to read pay, and an event when a run is approved.
Messaging
- Slack or Teamswe call it
- The same events, posted into a channel through an incoming webhook.
Calendars
- Calendarwe call it
- Absences published as a feed, so leave shows up beside meetings.
Anything else
- Another applicationboth ways
- A key for a system that reads or writes through the API: people, leave, attendance and pay.
- Send events to a URLwe call it
- We POST to an address when something happens — a leave approved, a payslip published, somebody joining.
- Something elseboth ways
- Anything not on this list. A named connection, an optional address for our events, and a log of what passed.
Webhooks
When something happens in your company, we POST a JSON body to the address you gave us, over HTTPS only — a plain-http endpoint is refused, because the body carries what happened inside your company.
Headers
x-staffena-event— what happened, for exampleleave.approved.x-staffena-signature— HMAC-SHA256 of the exact body, hex, keyed with the signing secret shown to you once when the connection was made.content-type: application/json.
Verify by recomputing the HMAC over the raw body before parsing it: a re-serialised body is a different string and will not match. Compare in constant time. The previous header names are still sent beside these for endpoints written before the product was renamed.
A delivery that does not answer 2xx within ten seconds is recorded as failed and shown on the connection, with the status the far end returned.
Keys
- Made in Settings → API, with the scopes that integration needs and nothing else.
- Shown once. We keep a digest, not the key — a key we could show you again is a key we could lose.
- Sent as
Authorization: Bearer …; the first eleven characters are kept in the clear so a call can be told apart in a log without being read. - Optionally pinned to a list of addresses, so a leaked key is useless elsewhere.
- Revoked instantly, and every call it ever made stays in the log.
Terminals at the door
A fingerprint, face or card reader posts punches to /api/attendance/punches with a device key in x-staffena-device-key. Each punch carries the device’s own identifier for the person and the moment it happened; the register fills in by itself, and a punch that arrives late is filed at the time it was taken rather than the time it landed. A device key is scoped to one terminal and can be revoked without touching any other.
The endpoint reference is on the API page.

