Skip to main content
POST
cURL

Authorizations

X-Api-Key
string
header
required

API key provided by Jobo

Body

application/json

Cursor-paginated export request. The cursor preserves the filters and batch size from the first request; start a new scan to change them.

locations
object[] | null
sources
string[] | null
work_models
enum<string>[] | null

Filter by work model: remote, hybrid, onsite. null = all jobs

Available options:
remote,
hybrid,
onsite
employment_types
enum<string>[] | null

Filter by employment type. null = all jobs

Available options:
full-time,
part-time,
contract,
internship,
freelance,
temporary
experience_levels
enum<string>[] | null

Filter by experience level. null = all jobs

Available options:
intern,
entry,
mid,
senior,
lead,
executive
languages
string[] | null

Filter by description language, as ISO 639-1 codes (en, de, fr). Language names and locales (English, en-US) are mapped to their code. null = all jobs.

exclude_sources
string[] | null

Leave out jobs from these ATS provider IDs (e.g. lever, workday), normalized like sources. May be combined with sources: sources: [greenhouse, lever] with exclude_sources: [lever] returns Greenhouse jobs.

exclude_work_models
enum<string>[] | null

Leave out jobs with these work models. Jobs whose work model is unknown are kept.

Available options:
remote,
hybrid,
onsite
exclude_employment_types
enum<string>[] | null

Leave out jobs with these employment types. Jobs whose employment type is unknown are kept.

Available options:
full-time,
part-time,
contract,
internship,
freelance,
temporary
exclude_experience_levels
enum<string>[] | null

Leave out jobs at these experience levels. Jobs whose experience level is unknown are kept.

Available options:
intern,
entry,
mid,
senior,
lead,
executive
exclude_languages
string[] | null

Leave out jobs whose description is in these languages, as ISO 639-1 codes; names and locales are mapped as for languages. Jobs whose language is unknown are kept.

companies
object | null

Include/exclude companies, resolved exactly as companies on POST /api/jobs/search: each entry is a Jobo company id GUID, a website domain or URL (fedex.com) matched on the company's stored website domain, or anything else a whole company display name (FedEx), matched case-insensitively after normalization — not a partial match. Resolved on the first page only: the cursor keeps the company ids the entries matched, so a scan's companies are fixed when it starts. Entries that match nothing are not a 400; they come back in the first page's warnings as companies_unmatched (include) or companies_exclude_unmatched (exclude), and as companies_outside_sources when the matched companies are on none of the requested sources. When no include entry matches, or it matches only companies outside sources, the first page is empty: jobs: [], has_more: false, next_cursor: null, estimated_total: 0, not billed.

job_categories
object | null

Include/exclude filter on the job's occupation category (occupation.category, e.g. Healthcare). Exact, case-insensitive match. GET /api/occupations lists every value. Jobs without an occupation never match an include list.

job_subcategories
object | null

Include/exclude filter on the job's occupation subcategory (occupation.subcategory, e.g. Nursing). Exact, case-insensitive match. GET /api/occupations lists every value.

occupation_ids
object | null

Include/exclude filter on occupation id (occupation.id, e.g. esco:8d3e8aaa-791b-4c75-a465-f3f827028f50). Use ids, not names: names can improve between taxonomy releases, ids don't. GET /api/occupations lists every id.

industries
object | null

Include/exclude filter on the hiring company's industries (company.industries, e.g. Software Development), matched on the whole name, case-insensitively. A job matches an include list if its company has ANY of the values, and an exclude list if it has none of them.

company_primary_industries
object | null

Include/exclude filter on the company's single primary industry (primary_industry on the company profile, GET /api/companies/{id}, e.g. Finance). Exact, case-insensitive match.

company_categories
object | null

Include/exclude filter on the hiring company's business model (categories on the company profile, GET /api/companies/{id}): b2b, b2c, b2b2c, saas, marketplace, service-provider. A job matches an include list if its company has ANY of them, and an exclude list if it has none of them. Case-insensitive.

company_sizes
object | null

Include/exclude filter on the company's headcount band (company_size on the company profile, GET /api/companies/{id}). Companies of unknown size never match an include list and are kept by an exclude list. An unknown band is a 400.

company_revenues
object | null

Include/exclude filter on the company's annual revenue band (revenue on the company profile, GET /api/companies/{id}). Companies of unknown revenue never match an include list and are kept by an exclude list. An unknown band is a 400.

company_is_agency
boolean | null

false leaves out jobs that recruitment and staffing agencies post on behalf of other employers (is_agency on the company profile, GET /api/companies/{id}); true returns only theirs. Omit or null = all jobs.

posted_after
string<date-time> | null

Return jobs whose employer posting time or first-indexed time is on or after this UTC timestamp. Use updated_after when edits matter.

include_reactivated
boolean
default:false

Also return jobs that expired and were reactivated (rediscovered and re-indexed) on or after posted_after. A reactivated job keeps its original posting and creation dates, so posted_after alone never re-delivers it.

Only changes the posted_after filter: it has no effect without posted_after, and an updated_after sync does not need it — reactivation re-indexes the job, so updated_after already returns it. When both posted_after and updated_after are set, a job must match both.

description_format
enum<string>
default:markdown

Format of each job's description. markdown (default) returns it as stored. html renders it to HTML on the fly: raw HTML in the source is escaped and only http(s), mailto and relative URLs are kept. Read from every request, including cursor continuations.

Available options:
markdown,
html
updated_after
string<date-time> | null

Return jobs created, updated or re-indexed on or after this UTC timestamp. Includes jobs that expired and were reactivated in the window (reactivation re-indexes the job), so syncs that use updated_after don't need include_reactivated.

stable_scan
boolean
default:true

Page by immutable creation time rather than update recency (default). Stable scans cannot skip or duplicate records when jobs are updated or deleted mid-scan. Set false explicitly for the legacy update-recency ordering.

cursor
string | null

Opaque cursor from next_cursor. Omit on the first request.

batch_size
integer
default:1000
Required range: 1 <= x <= 1000

Response

Match count and the first jobs of the feed

estimated_total
integer<int64>
required

Number of jobs POST /api/jobs/feed would deliver for the same request, as estimated_total on its first page: exact when 1,000 or fewer jobs match, above that an estimate that can run a few percent high. 0 when no companies.include entry matches.

jobs
object[]
required

Up to five jobs the feed's first page starts with, as preview cards: each description is Markdown, cut to at most 500 characters; summary is null and qualifications, responsibilities and benefits are empty.

Maximum array length: 5
warnings
object[]

Non-fatal problems with the request, as on the feed's first page: e.g. a companies entry that matched no company (companies_unmatched, companies_exclude_unmatched, companies_outside_sources). Present only when there is something to report. The same codes are on the X-Jobo-Warnings response header, comma-separated.