Sandbox search (no key)
Sandbox search (no key). Same request and response shape as `POST /jobs/search`, no auth required.
Cost: FreeFree. Fixed illustrative data.
const url = 'https://api.betterjobs.cc/v1/sandbox/jobs/search';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"filters":{"title_or":["Head of RevOps"],"country_code_or":["DE","AT","CH"],"posted_within_days":7},"limit":10}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.betterjobs.cc/v1/sandbox/jobs/search \ --header 'Content-Type: application/json' \ --data '{ "filters": { "title_or": [ "Head of RevOps" ], "country_code_or": [ "DE", "AT", "CH" ], "posted_within_days": 7 }, "limit": 10 }'Same request and response shape as POST /jobs/search, no auth required.
Returns fixed illustrative data. Nothing is charged and no provider is called.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Filter grammar with suffix operators. Unknown fields return 400 unknown_filter.
object
Match any of these title keywords.
Exclude titles containing any of these.
ISO 3166-1 alpha-2 codes.
Jobs first seen within this many days.
true remote only, false non-remote only, null or omitted = any.
Keep jobs whose salary.min is at least this value (yearly, in the job’s currency). Jobs with salary null are excluded when set.
Include jobs with status: closed.
How BetterJobs routes the request across providers.
object
cheapest_first stops once enough unique jobs are found, starting with the BetterJobs index.
freshest_first tries the sources with the fastest refresh first.
max_coverage queries every provider on your plan.
consensus returns only jobs seen by at least min_sources sources.
own_only uses the BetterJobs index only.
Override the providers to query. Must be enabled on your plan.
Hard cap on credits this request may charge. Results stop at the cap.
Per-request time budget. Slow providers are dropped and the result is partial.
Minimum agreeing sources for consensus.
next_cursor from the previous page.
Return a free estimate without fetching.
Examples
{ "filters": { "title_or": [ "Head of RevOps" ], "country_code_or": [ "DE", "AT", "CH" ], "posted_within_days": 7 }, "limit": 10}Responses
Section titled “ Responses ”Fixed illustrative results.
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
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.
Pass as cursor for the next page. null = last page.
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
{ "data": [ { "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" ] }, { "provider": "theirstack", "provider_job_id": "ts_88213377", "url": "https://jobs.acme-robotics.example/revops-lead", "first_seen_at": "2026-10-08T07:12:00Z", "last_seen_at": "2026-10-11T04:02:00Z", "fields": [ "salary", "seniority" ] }, { "provider": "techmap", "provider_job_id": "tm_3f9a2c71", "url": "https://boards.example/acme-robotics/revops-lead", "first_seen_at": "2026-10-08T09:30:00Z", "last_seen_at": "2026-10-10T23:40:00Z", "fields": [ "job_family" ] } ], "license": { "display": true, "resale": false } } ], "next_cursor": null, "metadata": { "request_id": "req_sandbox_0001", "status": "complete", "credits_charged": 0, "jobs_already_paid": 0, "duplicates_merged": 2, "credits_remaining": 0, "providers": { "tried": [ "betterjobs", "techmap", "theirstack" ], "hit": [ "betterjobs", "techmap", "theirstack" ], "failed": [], "contributions": { "betterjobs": 1, "techmap": 0, "theirstack": 0 } }, "field_coverage": { "salary": 1, "seniority": 1, "location.remote": 1, "description": 1 }, "latency_ms": 12 }}Headers
Section titled “Headers”Example
req_7Hc2LmQ9xTUnique id for this request. Quote it to support.
Invalid request (invalid_request) or unknown filter field (unknown_filter).
object
object
Present on insufficient_credits.
Present on insufficient_credits and plan_required.
Offending field on invalid_request and unknown_filter.
Examples
unknown_filter
{ "error": { "type": "invalid_request_error", "code": "unknown_filter", "message": "Unknown filter field 'job_title_or'. Did you mean 'title_or'?", "param": "filters.job_title_or", "doc_url": "https://docs.betterjobs.cc/platform/errors/#unknown_filter", "request_id": "req_4Bn8CxV2zA" }}invalid_request
{ "error": { "type": "invalid_request_error", "code": "invalid_request", "message": "limit must be between 1 and 100.", "param": "limit", "doc_url": "https://docs.betterjobs.cc/platform/errors/#invalid_request", "request_id": "req_2Cm7DwB1yZ" }}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.