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.
const url = 'https://api.betterjobs.cc/v1/searches/srch_2Vd9KqL4mN?cursor=cur_8fJ2kQ&limit=100';const options = { method: 'GET', headers: {'BetterJobs-Version': '2026-10-01', Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters”Example
srch_2Vd9KqL4mNSearch id (srch_...).
Header Parameters
Section titled “Header Parameters”Example
2026-10-01Date-pinned API version. Changes within a version are additive only. Defaults to your account’s pinned version.
Query Parameters
Section titled “Query Parameters”Example
cur_8fJ2kQOpaque cursor from a previous next_cursor.
Results per page.
Responses
Section titled “ Responses ”Search state.
Async search. Branch on status, not on the HTTP code.
object
on_hold = out of credits; resumes after a top-up. partial = finished but at least one provider failed.
Unique jobs collected so far.
A page of results once completed or partial. Empty otherwise.
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
Canonical job id. Stable across sources and requests.
Company reference embedded in jobs, events and profiles.
object
Primary web domain. null when unknown.
object
ISO 3166-1 alpha-2.
true remote, false on-site or hybrid, null unknown.
Plain-text job description.
Date the employer posted the job, if known.
Earliest time any source saw the job.
Latest time any source saw the job.
Latest time the job was confirmed live at its origin.
Why the job closed. null while open.
Times the same job was re-listed.
Probability (0-1) that the job is a real open req, from cross-source corroboration.
One provider’s view of the canonical job.
object
Source slug. betterjobs is the BetterJobs index.
Job fields this source contributed to the canonical record.
object
You may show this job to your end users.
You may resell or redistribute this job as data.
object
partial = at least one provider failed or timed out. You are billed only for returned jobs.
Returned jobs you had already paid for (free).
Provider records merged into existing canonical jobs (free).
object
Providers that returned at least one match.
object
Source slug. betterjobs is the BetterJobs index.
provider_timeout = the provider missed timeout_ms. provider_error = the provider returned an error.
Unique jobs each provider contributed first.
object
Fraction (0-1) of returned jobs with a non-null value, per field.
object
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}Out of credits
{ "id": "srch_2Vd9KqL4mN", "status": "on_hold", "created_at": "2026-10-11T09:00:00Z", "updated_at": "2026-10-11T09:04:10Z", "completed_at": null, "webhook_url": "https://hooks.northwind.example/betterjobs", "jobs_found": 2210, "data": [], "next_cursor": null, "metadata": null}Completed with results
{ "id": "srch_2Vd9KqL4mN", "status": "completed", "created_at": "2026-10-11T09:00:00Z", "updated_at": "2026-10-11T09:06:45Z", "completed_at": "2026-10-11T09:06:45Z", "webhook_url": "https://hooks.northwind.example/betterjobs", "jobs_found": 3184, "data": [ { "id": "job_01JC9F2K7NQ3XW5R8T1Y6M4H0C", "title": "Senior Data Engineer", "company": { "id": "cmp_2Lm8QwE5rT", "name": "Contoso Health", "domain": "contoso-health.example" }, "location": { "city": "Amsterdam", "region": "North Holland", "country_code": "NL", "remote": true }, "employment_type": "full_time", "seniority": "senior", "job_family": "engineering", "salary": null, "description": "Build and run the batch and streaming pipelines behind Contoso Health's clinical analytics.", "apply_url": "https://careers.contoso-health.example/jobs/4471", "posted_at": null, "first_seen_at": "2026-10-02T11:00:00Z", "last_seen_at": "2026-10-11T05:20:00Z", "last_verified_at": "2026-10-10T22:00:00Z", "status": "open", "closed_reason": null, "repost_count": 1, "p_real": 0.88, "sources": [ { "provider": "jobspipe", "provider_job_id": "jp_77120983", "url": "https://careers.contoso-health.example/jobs/4471", "first_seen_at": "2026-10-02T11:00:00Z", "last_seen_at": "2026-10-11T05:20:00Z", "fields": [ "title", "description", "apply_url", "location", "seniority", "employment_type" ] }, { "provider": "coresignal", "provider_job_id": "cs_410298811", "url": "https://careers.contoso-health.example/jobs/4471", "first_seen_at": "2026-10-03T02:15:00Z", "last_seen_at": "2026-10-10T22:00:00Z", "fields": [ "job_family" ] } ], "license": { "display": true, "resale": false } } ], "next_cursor": "cur_Lp0sR3", "metadata": { "request_id": "req_5Tg1HsW8cV", "status": "complete", "credits_charged": 3012, "jobs_already_paid": 172, "duplicates_merged": 1907, "credits_remaining": 6829, "providers": { "tried": [ "betterjobs", "reqbeat", "signalsapi", "theirstack", "jobspipe", "coresignal", "techmap" ], "hit": [ "betterjobs", "reqbeat", "signalsapi", "theirstack", "jobspipe", "coresignal", "techmap" ], "failed": [], "contributions": { "betterjobs": 1210, "reqbeat": 402, "signalsapi": 95, "theirstack": 610, "jobspipe": 388, "coresignal": 241, "techmap": 238 } }, "field_coverage": { "salary": 0.41, "seniority": 0.97, "location.remote": 0.88, "description": 0.99 }, "latency_ms": 405112 }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.
Example
60Requests allowed in the current window.
Example
59Requests left in the current window.
Example
42Seconds until the window resets.
Missing or invalid API key.
object
object
Present on insufficient_credits.
Present on insufficient_credits and plan_required.
Offending field on invalid_request and unknown_filter.
Examples
{ "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" }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.
The resource does not exist.
object
object
Present on insufficient_credits.
Present on insufficient_credits and plan_required.
Offending field on invalid_request and unknown_filter.
Examples
{ "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" }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.
Too many requests. Wait Retry-After seconds.
object
object
Present on insufficient_credits.
Present on insufficient_credits and plan_required.
Offending field on invalid_request and unknown_filter.
Examples
{ "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" }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.
Example
12Seconds to wait before retrying.
Example
60Requests allowed in the current window.
Example
59Requests left in the current window.
Example
42Seconds until the window resets.
Something failed on our side. Safe to retry with the same Idempotency-Key.
object
object
Present on insufficient_credits.
Present on insufficient_credits and plan_required.
Offending field on invalid_request and unknown_filter.
Examples
{ "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" }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.