Skip to content

Webhooks and events

Send signed webhooks to your own systems when jobs, applications, candidates, offers and postings change, refresh your website's job pages, and see which events Careers Orbit sends.

Reference5 min read

Careers Orbit tells other systems what happened in two ways:

  • Webhooks under Webhooks send the events you choose to your own systems, such as an HR system. They are in the Growth and Enterprise plans.
  • The website webhook under Settings › Website webhook tells your website when a job is published, changed or closed, so it can refresh its job pages. It is in every plan.

Webhooks to your own systems

Admins add them under Webhooks, for example to tell an HR system when someone is hired at Northwilds.

  1. Choose New webhook, give it a name and the address, such as https://hr.northwilds.com/hooks/careers. It must start with https://.
  2. Tick the events to send. Each is listed under Careers events below.
  3. Leave Trusted endpoint off unless the system is your own and your privacy notice covers it.
  4. Copy the signing secret. It starts with whsec_ and is shown once; New secret on the webhook's page replaces it.

Each delivery is a POST with JSON such as:

JSON
{  "id": "4f0c…",  "event": "careers.application.hired",  "time": "2026-10-27T09:12:00.000Z",  "organisationId": "…",  "subject": { "resourceType": "application", "id": "…" },  "actor": { "type": "user", "id": "…" },  "data": { "applicationId": "…", "jobId": "…", "candidateId": "…", "stageId": "hired", "stageType": "hired", "source": "linkedin" },  "attempt": 1}

and these headers:

  • x-orbit-event: the event type
  • x-orbit-delivery: the delivery's id, the same on every try, so you can ignore repeats
  • x-orbit-timestamp: the time it was sent, in milliseconds
  • x-orbit-signature: the HMAC-SHA256 of {timestamp}.{body} with your secret, in hex
  • User-Agent: Careers-Orbit-Webhooks/1

Check the signature against the raw body and refuse messages older than five minutes. In Node.js:

TypeScript
import { createHmac, timingSafeEqual } from 'node:crypto';export function verify(secret: string, timestamp: string, body: string, signature: string): boolean {  if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60_000) return false;  const expected = createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex');  return expected.length === signature.length && timingSafeEqual(Buffer.from(expected), Buffer.from(signature));}

Ids, or contact details too

Payloads carry ids only, so a system can look up what it needs through the management API. A trusted webhook also gets data.candidate with the candidate's firstName, lastName, email and phone on events that name a candidate, and only a trusted webhook may receive careers.notification, the hiring team's notifications, which name candidates. Erasing a candidate removes their details from the delivery log too.

Retries and the log

Answer with a 2xx status within ten seconds. Redirects are not followed and count as a failure. After a failure, Careers Orbit tries again after 1, 2, 4, 8 minutes and so on, at most 6 hours apart and 8 tries in all. After 20 failed deliveries in a row the webhook turns itself off; Turn on starts it again.

Open a webhook to see its latest deliveries from the past 30 days, with the status code, time taken, error and exact JSON. Send again repeats any of them, and Send a test sends careers.webhook.test once to check the address and your signature check. Moving a webhook to the bin stops it.

The website webhook

Set it under Settings › Website webhook, pointing at your website, for example https://northwilds.com/api/careers/revalidate/. Careers Orbit shows a signing secret once; keep it in your website's environment.

When a job is published, changed or closed, Careers Orbit posts JSON such as:

JSON
{ "event": "careers.job.closed", "data": { "jobId": "...", "slug": "mountain-guide-lofoten", "title": "Mountain guide, Lofoten", "status": "closed", "departmentId": "...", "locationIds": ["..."] } }

with x-orbit-timestamp and x-orbit-signature, signed in the same way. Answer within five seconds. A failed delivery is tried again with growing waits, up to ten times.

The Careers SDK's createRevalidateHandler checks the signature and the age and refreshes the careers:jobs and careers:job:<slug> cache tags. The PHP SDK has Webhook::verify and Webhook::tags for the same job.

Careers events

careers.job.published
When
A job goes live, at once or at its scheduled time
data
jobId, slug, title, status, departmentId, locationIds
careers.job.updated
When
A live job changes
data
as above
careers.job.closed
When
A job closes, by hand, on its closing date or by going to the bin
data
as above
careers.review.requested
When
A job ad is sent for review
data
jobId, title, requestedBy, note
careers.application.created
When
A new application arrives
data
applicationId, jobId, candidateId, stageId, stageType, source
careers.application.stageChanged
When
An application moves to another stage
data
as above, and fromStageId
careers.application.rejected
When
An application is rejected
data
as above, and reason
careers.application.withdrawn
When
A candidate withdraws
data
as for created
careers.application.hired
When
An application ends in a hire
data
as for created
careers.candidate.erased
When
A candidate's data is erased, by hand, on request or by your retention rules. Erase your copies too
data
candidateId, applications, files (how many went)
careers.posting.statusChanged
When
A job's posting on a job board changes
data
jobId, channel, status (incomplete, pending, live, rejected, failed or unpublished), reason
careers.campaign.sent
When
A talent pool campaign or a new job alert has finished going out
data
campaignId, kind (campaign or alert), jobId, recipients, sent
careers.referral.created
When
Someone in your team refers a person, or a person applies through a referral link
data
referralId, jobId, referrerId, invited
careers.assessment.completed
When
A candidate completes an assessment or video interview
data
assessmentId, applicationId, jobId, candidateId, kind (assessment or video), provider. Never the score
careers.offer.sent, .accepted, .declined
When
An offer goes to a candidate, and they accept or decline it
data
offerId, applicationId, jobId, candidateId, status
careers.notification
When
A notification to the hiring team. Trusted webhooks only
data
id, recipient, kind, title, detail, url, createdAt

Every event is version 1 and carries your organisation, a sequence number and who caused it (actor.type is user or system). Careers Orbit also sends these events to Orbit Exchange, where other Orbit satellites and Orbit's Exchange page see them. To receive them in your own systems, use a webhook.

Was this page helpful?

Read next