Skip to content
API v1 preview — endpoints and fields may change before general availability.

Event delivery

Event delivery. BetterJobs POSTs one `Event` per request to your `webhook_url`.

Cost: 1 credit / job.opened1 credit per job.opened delivered for a job you have not already paid for. Other events, retries and replays are free.

POST

BetterJobs POSTs one Event per request to your webhook_url.

Verify BetterJobs-Signature: t=<unix>,v1=<hex>: compute HMAC-SHA256 over <t>.<raw body> with your endpoint secret and compare to v1 in constant time. t is the time this delivery attempt was sent: every retry and replay is signed again, so you can reject a t more than 5 minutes from your clock.

Return any 2xx within 10 seconds. Failed deliveries retry with backoff for 24 hours, at 1m, 5m, 30m, 2h, 6h, 12h and 24h after the first failed attempt. Replay any event with POST /webhooks/replay.

Act on job.opened for outbound. Do not re-trigger outbound on job.reposted.

BetterJobs-Signature
required
string
Example
t=1760173200,v1=5f2b7c1e9a4d3f6b8c0e2a4d6f8b0c2e4a6d8f0b2c4e6a8d0f2b4c6e8a0d2f4b

t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">

Media typeapplication/json

Typed event envelope. data carries the objects relevant to type: job for job events, company and is_hiring for company events, search for search.completed.

object
id
required
string
/^evt_/
type
required
string
Allowed values: job.opened job.reposted job.closed job.updated company.hiring_started company.hiring_stopped search.completed
created_at
required
string format: date-time
watch_id
required

Watch that produced the event. null for search.completed.

string | null
data
required
object
job

Canonical job. Full Job for job.opened and job.updated; id, title, company, status and lifecycle fields otherwise.

object
company

Company reference embedded in jobs, events and profiles.

object
id
required
string
/^cmp_/
name
required
string
domain
required

Primary web domain. null when unknown.

string | null
is_hiring
object
value
required

null = unknown. Never treat null as false.

boolean | null
confidence
required
number
<= 1
basis
required

Plain-English reason for the value.

string
search
object
id
string
status
string
jobs_found
integer
Examples

job.opened

{
"id": "evt_7Wq1ZxC4vB",
"type": "job.opened",
"created_at": "2026-10-11T06:15:00Z",
"watch_id": "wat_6Np3QyR8tU",
"data": {
"job": {
"id": "job_01JC8X4M2Q7RV3T9KD5W6YH0AB",
"title": "Head of Revenue Operations",
"company": {
"id": "cmp_4Rk7TzP1aQ",
"name": "Acme Robotics",
"domain": "acme-robotics.example"
},
"location": {
"city": "Berlin",
"region": "Berlin",
"country_code": "DE",
"remote": false
},
"employment_type": "full_time",
"seniority": "lead",
"job_family": "operations",
"salary": {
"min": 110000,
"max": 135000,
"currency": "EUR",
"period": "year",
"origin": "declared"
},
"description": "Acme Robotics is hiring a Head of Revenue Operations to own forecasting, CRM hygiene and the GTM tool stack across DACH.",
"apply_url": "https://jobs.acme-robotics.example/revops-lead/apply",
"posted_at": "2026-10-08T00:00:00Z",
"first_seen_at": "2026-10-08T06:40:00Z",
"last_seen_at": "2026-10-11T06:10:00Z",
"last_verified_at": "2026-10-11T06:10:00Z",
"status": "open",
"closed_reason": null,
"repost_count": 0,
"p_real": 0.94,
"sources": [
{
"provider": "betterjobs",
"provider_job_id": "bj_idx_5521907",
"url": "https://jobs.acme-robotics.example/revops-lead",
"first_seen_at": "2026-10-08T06:40:00Z",
"last_seen_at": "2026-10-11T06:10:00Z",
"fields": [
"title",
"description",
"apply_url",
"location",
"employment_type",
"posted_at"
]
}
],
"license": {
"display": true,
"resale": false
}
}
}
}

Return any 2xx to acknowledge.