Skip to main content
andteam POSTs an employee event to your endpoint when a person joins, changes or leaves. An administrator adds an endpoint under Settings, Integrations, Webhooks, chooses its events and companies, and copies its signing secret. A sandbox tenant cannot add one. A receiver does three things, in this order: verify the signature against the raw body, store the event and answer 2xx, then do the work.

Events

A dated change is sent when it takes effect, not when it was entered. GET /v1/events returns the same events for a consumer that cannot receive them.

The payload

A delivery is thin by default: ids, dates and the names of changed fields, never values. Read the record from the API when you need it.
data.startDate and data.lastDay are added to the events they belong to. Include details. An endpoint can switch on Include details. The payload then carries details: the employee resource, limited to the endpoint’s field groups, exactly as GET /v1/employees/{id} would return it for a key with those groups. Fields outside the groups are left out, not sent as null, and changedFields names only fields the groups open. Special categories are delivered only after the Information Officer approves them for the endpoint.

Signing

Every request carries three headers, as in the Standard Webhooks specification:
  • webhook-id is the event id. It is the same on every attempt and on a resend.
  • webhook-timestamp is Unix time in seconds, of this attempt.
  • webhook-signature is v1, followed by the base64 of an HMAC-SHA256.
The signed content is the three values joined by dots: id.timestamp.body, where body is the raw request body, byte for byte. Parse the JSON only after it verifies; a body re-serialised from parsed JSON will not match. The signing secret looks like whsec_ followed by base64. The HMAC key is the base64-decoded part after whsec_, not the string itself.

Rolling a secret

When an administrator rolls an endpoint’s secret, the old one keeps signing for 24 hours. During that time the header carries both signatures, separated by a space: v1,<new> v1,<old>. Accept the request if any one matches, so you can swap the secret on your side at any moment in the 24 hours.

Reject old requests

Refuse a request whose webhook-timestamp is more than 5 minutes from your clock, either way. This stops a captured request from being replayed.

Verifying a delivery

Libraries for most languages do the same: see standardwebhooks (npm standardwebhooks, and Python, Go, Ruby, Java, Rust, PHP and C# packages). Give them the whole whsec_… secret.

Delivery

  • Answer with any 2xx within 15 seconds. A redirect is not followed and counts as a failure.
  • Retries. A failed delivery is tried again after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours: eight attempts over about 27 and a half hours. After the eighth it is marked failed and kept in the delivery log, where an administrator can resend it.
  • 410 Gone disables the endpoint at once. Use it to retire an endpoint.
  • Five days of nothing but failures disables the endpoint too.
  • At least once. The same event can arrive more than once: ignore an id you have already handled.
  • Not ordered. Retries mean events can arrive out of order. Order by occurredAt, and for one person by sequence: drop an event older than the last sequence you saw for that person.
  • The delivery log keeps 30 days.