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

Get an async search

Get an async search. Returns the search status and, once `completed` or `partial`, a page of results.

Cost: FreeFree. Jobs are charged when the search collects them, not when you read results.

GET
/searches/{id}
curl --request GET \
--url 'https://api.betterjobs.cc/v1/searches/srch_2Vd9KqL4mN?cursor=cur_8fJ2kQ&limit=100' \
--header 'Authorization: Bearer <token>' \
--header 'BetterJobs-Version: 2026-10-01'

Returns the search status and, once completed or partial, a page of results. Page through results with cursor. Branch on status, not on the HTTP code. on_hold means you ran out of credits; the search resumes after a top-up.

id
required
string
/^srch_/
Example
srch_2Vd9KqL4mN

Search id (srch_...).

BetterJobs-Version
string
Allowed values: 2026-10-01
Example
2026-10-01

Date-pinned API version. Changes within a version are additive only. Defaults to your account’s pinned version.

cursor
string
Example
cur_8fJ2kQ

Opaque cursor from a previous next_cursor.

limit
integer
default: 100 >= 1 <= 100

Results per page.

Search state.

Media typeapplication/json

Async search. Branch on status, not on the HTTP code.

object
id
required
string
/^srch_/
status
required

on_hold = out of credits; resumes after a top-up. partial = finished but at least one provider failed.

string
Allowed values: queued running completed partial failed on_hold
created_at
required
string format: date-time
updated_at
required
string format: date-time
completed_at
required
string | null format: date-time
webhook_url
required
string | null format: uri
jobs_found
required

Unique jobs collected so far.

integer
data
required

A page of results once completed or partial. Empty otherwise.

Array<object>

A canonical job: one real opening, merged from every source that saw it. Null semantics: null = unknown; [] = verified none; field omitted = not part of this payload (for example the lifecycle-only job in job.closed and job.reposted events).

object
id
required

Canonical job id. Stable across sources and requests.

string
/^job_/
title
required
string
company
required

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
location
required
object
city
required
string | null
region
required
string | null
country_code
required

ISO 3166-1 alpha-2.

string | null
remote
required

true remote, false on-site or hybrid, null unknown.

boolean | null
employment_type
required
One of:
string
Allowed values: full_time part_time contract internship temporary
seniority
required
One of:
string
Allowed values: intern junior mid senior lead director vp c_level
job_family
required
string | null
salary
required
One of:
object
min
required
number | null
max
required
number | null
currency
required

ISO 4217.

string
period
required
string
Allowed values: year month hour
origin
required

declared = stated in the posting. inferred = estimated by a source.

string
Allowed values: declared inferred
description
required

Plain-text job description.

string | null
apply_url
required
string | null format: uri
posted_at
required

Date the employer posted the job, if known.

string | null format: date-time
first_seen_at
required

Earliest time any source saw the job.

string format: date-time
last_seen_at
required

Latest time any source saw the job.

string format: date-time
last_verified_at
required

Latest time the job was confirmed live at its origin.

string | null format: date-time
status
required
string
Allowed values: open closed
closed_reason
required

Why the job closed. null while open.

string | null
Allowed values: filled expired removed unknown
repost_count
required

Times the same job was re-listed.

integer
p_real
required

Probability (0-1) that the job is a real open req, from cross-source corroboration.

number
<= 1
sources
required
Array<object>

One provider’s view of the canonical job.

object
provider
required

Source slug. betterjobs is the BetterJobs index.

string
Allowed values: betterjobs reqbeat signalsapi theirstack jobspipe coresignal techmap
provider_job_id
required
string
url
required
string | null format: uri
first_seen_at
required
string format: date-time
last_seen_at
required
string format: date-time
fields
required

Job fields this source contributed to the canonical record.

Array<string>
license
required
object
display
required

You may show this job to your end users.

boolean
resale
required

You may resell or redistribute this job as data.

boolean
next_cursor
required
string | null
metadata
required
One of:
object
request_id
required
string
status
required

partial = at least one provider failed or timed out. You are billed only for returned jobs.

string
Allowed values: complete partial
credits_charged
required
integer
jobs_already_paid
required

Returned jobs you had already paid for (free).

integer
duplicates_merged
required

Provider records merged into existing canonical jobs (free).

integer
credits_remaining
required
integer
providers
required
object
tried
required
Array<string>
Allowed values: betterjobs reqbeat signalsapi theirstack jobspipe coresignal techmap
hit
required

Providers that returned at least one match.

Array<string>
Allowed values: betterjobs reqbeat signalsapi theirstack jobspipe coresignal techmap
failed
required
Array<object>
object
provider
required

Source slug. betterjobs is the BetterJobs index.

string
Allowed values: betterjobs reqbeat signalsapi theirstack jobspipe coresignal techmap
code
required

provider_timeout = the provider missed timeout_ms. provider_error = the provider returned an error.

string
Allowed values: provider_timeout provider_error
contributions
required

Unique jobs each provider contributed first.

object
key
additional properties
integer
field_coverage
required

Fraction (0-1) of returned jobs with a non-null value, per field.

object
key
additional properties
number
<= 1
latency_ms
required
integer
Examples

Still running

{
"id": "srch_2Vd9KqL4mN",
"status": "running",
"created_at": "2026-10-11T09:00:00Z",
"updated_at": "2026-10-11T09:01:30Z",
"completed_at": null,
"webhook_url": "https://hooks.northwind.example/betterjobs",
"jobs_found": 1260,
"data": [],
"next_cursor": null,
"metadata": null
}
X-Request-Id
string
Example
req_7Hc2LmQ9xT

Unique id for this request. Quote it to support.

RateLimit-Limit
integer
Example
60

Requests allowed in the current window.

RateLimit-Remaining
integer
Example
59

Requests left in the current window.

RateLimit-Reset
integer
Example
42

Seconds until the window resets.

Missing or invalid API key.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error billing_error permission_error not_found_error conflict_error rate_limit_error api_error
code
required
string
Allowed values: invalid_request unknown_filter unauthorized insufficient_credits plan_required not_found idempotency_conflict rate_limited internal_error
message
required
string
doc_url
required
string format: uri
request_id
required
string
credits_needed

Present on insufficient_credits.

integer
required_plan
string
Allowed values: free starter growth pro scale enterprise
upgrade_url

Present on insufficient_credits and plan_required.

string format: uri
param

Offending field on invalid_request and unknown_filter.

string
key
additional properties
any
Examples
Exampleunauthorized
{
"error": {
"type": "authentication_error",
"code": "unauthorized",
"message": "Missing or invalid API key. Send 'Authorization Bearer bj_live_...'.",
"doc_url": "https://docs.betterjobs.cc/platform/errors/#unauthorized",
"request_id": "req_5Dl6EvN0xY"
}
}
X-Request-Id
string
Example
req_7Hc2LmQ9xT

Unique id for this request. Quote it to support.

The resource does not exist.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error billing_error permission_error not_found_error conflict_error rate_limit_error api_error
code
required
string
Allowed values: invalid_request unknown_filter unauthorized insufficient_credits plan_required not_found idempotency_conflict rate_limited internal_error
message
required
string
doc_url
required
string format: uri
request_id
required
string
credits_needed

Present on insufficient_credits.

integer
required_plan
string
Allowed values: free starter growth pro scale enterprise
upgrade_url

Present on insufficient_credits and plan_required.

string format: uri
param

Offending field on invalid_request and unknown_filter.

string
key
additional properties
any
Examples
ExamplenotFound
{
"error": {
"type": "not_found_error",
"code": "not_found",
"message": "No job with id 'job_01JC00000000000000000000XX'.",
"doc_url": "https://docs.betterjobs.cc/platform/errors/#not_found",
"request_id": "req_8Gi3HsK7uV"
}
}
X-Request-Id
string
Example
req_7Hc2LmQ9xT

Unique id for this request. Quote it to support.

Too many requests. Wait Retry-After seconds.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error billing_error permission_error not_found_error conflict_error rate_limit_error api_error
code
required
string
Allowed values: invalid_request unknown_filter unauthorized insufficient_credits plan_required not_found idempotency_conflict rate_limited internal_error
message
required
string
doc_url
required
string format: uri
request_id
required
string
credits_needed

Present on insufficient_credits.

integer
required_plan
string
Allowed values: free starter growth pro scale enterprise
upgrade_url

Present on insufficient_credits and plan_required.

string format: uri
param

Offending field on invalid_request and unknown_filter.

string
key
additional properties
any
Examples
ExamplerateLimited
{
"error": {
"type": "rate_limit_error",
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"doc_url": "https://docs.betterjobs.cc/platform/errors/#rate_limited",
"request_id": "req_0Ig1JqH5sT"
}
}
X-Request-Id
string
Example
req_7Hc2LmQ9xT

Unique id for this request. Quote it to support.

Retry-After
integer
Example
12

Seconds to wait before retrying.

RateLimit-Limit
integer
Example
60

Requests allowed in the current window.

RateLimit-Remaining
integer
Example
59

Requests left in the current window.

RateLimit-Reset
integer
Example
42

Seconds until the window resets.

Something failed on our side. Safe to retry with the same Idempotency-Key.

Media typeapplication/json
object
error
required
object
type
required
string
Allowed values: invalid_request_error authentication_error billing_error permission_error not_found_error conflict_error rate_limit_error api_error
code
required
string
Allowed values: invalid_request unknown_filter unauthorized insufficient_credits plan_required not_found idempotency_conflict rate_limited internal_error
message
required
string
doc_url
required
string format: uri
request_id
required
string
credits_needed

Present on insufficient_credits.

integer
required_plan
string
Allowed values: free starter growth pro scale enterprise
upgrade_url

Present on insufficient_credits and plan_required.

string format: uri
param

Offending field on invalid_request and unknown_filter.

string
key
additional properties
any
Examples
ExampleinternalError
{
"error": {
"type": "api_error",
"code": "internal_error",
"message": "Unexpected error. Retry with the same Idempotency-Key; you will not be charged twice.",
"doc_url": "https://docs.betterjobs.cc/platform/errors/#internal_error",
"request_id": "req_1Jf0KpG4rS"
}
}
X-Request-Id
string
Example
req_7Hc2LmQ9xT

Unique id for this request. Quote it to support.