Job Opportunity Index
Job feed API (v1) · On demand

Search, scraping if needed

One call for 'give me this': answers from the index when it holds at least min_results postings; otherwise it launches scraping for exactly this (the title / place / country through the public employment services, a company's career site with company_url) and answers with what exists now plus the request ids, or, with wait=N, waits for the scraping and answers with the fresh postings. Accepts every active-jobs filter.

GET /api/v1/search

Query parameters

Pagination

limitinteger · int32
Postings per response, 1 to 1000. Default 100.
Default: 100
offsetinteger · int32
Postings to skip, up to 100,000. Keep adding limit until a page comes back shorter than limit.
Default: 0
cursorinteger · int64
The last id you received; returns the next postings by id ascending. Best for backfills; every response also carries it in the X-Last-Id header. Wins over offset.

Response

description_formatstring · enum
text or html to include the full description (and requirements). Left out by default because it is large.
Enum values: texthtml
include_page_textboolean
true: also the complete text read from the original posting page.
Enum values: truefalse
Default: false
formatstring · enum
json (an array, the default), jsonl, csv, or md (Markdown for language models; chars limits text per posting).
Enum values: jsonjsonlcsvmd
Default: json
fieldsstring · comma-separated
Comma-separated list of the fields to return, e.g. id,title,url.
schemastring · enum
The output layout. Default: the universal job-feed layout (ai_* names for derived fields, salary / employment_type as the source states them), so code written for other job feeds works unchanged; the values are still derived by rules from the posting. native: this index's own names (no ai_ prefix).
Enum values: fantasticnative
Default: fantastic
include_basic_organization_detailsboolean
true: the employer's profile inline (industry, headcount, headquarters, legal entity id, open and new postings).
Enum values: truefalse
Default: false
include_betaboolean
true: also the standard occupation of each posting, classification_onet (O*NET-SOC 2019), classification_soc (SOC 2018) and classification_isco (ISCO-08), each {id, name}, matched by rules against O*NET's official title lists (English titles; null when no title matches), and locations_derived_structured (each place as lat, lon, locality, county, region, country, country_code, continent, timezone).
Enum values: truefalse
Default: false
order_bystring · enum
date_created (default, newest first), date_posted or salary.
Enum values: date_createddate_postedsalary
Default: date_created
include_duplicatesboolean
true: also the same opening found on a second channel.
Enum values: truefalse
Default: false

Text search

titlestring
Google-style search of the title: software engineer (both words), "software engineer" (phrase), python OR rust, -senior (exclude).
descriptionstring
The same syntax over the title and the complete description.
locationstring
The same syntax over the location, raw and normalised: Munich also finds München; "London, England, United Kingdom"; "United States" OR Canada.
title_advancedstring
Boolean: & and, | or, ! not, <-> followed by, <N> within N words, 'exact phrase', manag:* prefix, parentheses. E.g. (python | rust) & senior & !staff.
description_advancedstring
Boolean expression over title and description.
location_advancedstring
Boolean expression over the location: Germany & !(Berlin | Munich).
organization_advancedstring
Boolean expression over the employer's name.
skillstring
Comma-separated skills, all required: Python,SQL.

Dates

date_posted_gtestring · date-time
Posted on or after (ISO 8601, UTC).
date_posted_ltstring · date-time
Posted before.
date_created_gtestring · date-time
First indexed on or after: the safe cursor for incremental syncs.
date_created_ltstring · date-time
First indexed before.

Source

exclude_sourcestring
Sources to leave out.
source_typestring · enum · comma-separated
ats, career_site, public_employment_service.
Enum values: atscareer_sitepublic_employment_service

Employer

organizationstring
Exact employer names, comma-separated.
exclude_organizationstring
Employers to leave out.
domainstring
Employer domains: nvidia.com,microsoft.com.
exclude_domainstring
Domains to leave out.
organization_agencystring · enum
only staffing / placement agencies, or exclude them (direct employers only).
Enum values: onlyexclude
organization_industrystring
Sector, e.g. technology, finance, healthcare.
organization_sizestring · enum · comma-separated
Company size buckets, comma-separated: 1, 2-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+.
Enum values: 12-1011-5051-200201-500501-10001001-50005001-1000010001+
organization_headcount_gteinteger
At least this many employees.
organization_headcount_ltinteger
Fewer than this many employees.
company_countrystring
Employer's home country (ISO code).

Derived

experience_levelstring · enum · comma-separated
0-2, 2-5, 5-10, 10+ years (also as ai_experience_level).
Enum values: 0-22-55-1010+
work_arrangementstring · enum · comma-separated
On-site, Hybrid, Remote OK, Remote Solely.
Enum values: On-siteHybridRemote OKRemote Solely
employment_typestring · enum · comma-separated
FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER.
Enum values: FULL_TIMEPART_TIMECONTRACTORTEMPORARYINTERNVOLUNTEER
languagestring
Language the posting is written in: English, German, French, Spanish…
educationstring · enum · comma-separated
high school, associate degree, bachelor degree, postgraduate degree.
Enum values: high schoolassociate degreebachelor degreepostgraduate degree
taxonomiesstring
Job function, e.g. Software Engineering, Data & AI, Sales (also ai_taxonomies_a, function).
exclude_taxonomiesstring
Functions to leave out.
visa_sponsorshipstring · enum
only postings that offer sponsorship, or exclude them.
Enum values: onlyexclude
senioritystring · enum · comma-separated
internship, entry, mid, senior, lead, manager, director, executive.
Enum values: internshipentrymidseniorleadmanagerdirectorexecutive

Other

has_salaryboolean
true: only postings that state pay.
Enum values: truefalse
Default: false
salary_mininteger · per year
Minimum yearly pay (hourly, daily, weekly and monthly pay are converted).
currencystring
USD, EUR, GBP…
countrystring
ISO country codes of the job's location: US,CA.
has_no_locationboolean
true: only postings without a recognisable place.
Enum values: truefalse
Default: false
full_text_onlyboolean
true: only postings whose complete text is stored.
Enum values: truefalse
Default: false
idinteger · comma-separated
Posting ids, comma-separated.

Search

modestring · enum
index (default): only what is already in the database, answered in a fraction of a second. live: the database and live scraping at the same time for whatever is missing (takes up to wait seconds; the answer says what was added and what is still coming).
Enum values: indexlive
Default: index
min_resultsinteger
How many postings you want (default: limit). While the index holds fewer, the search scrapes for more at the same time: the hiring boards that had such postings before (ranked by what each actually delivered in earlier searches), the public employment services and Amazon for the place, and the place's own employers in the background.
Default: limit
waitinteger · seconds (0-120)
Seconds (0-120, default 45) to wait for the scraping it launches, then answer with what it found. 0 (default): answer at once with what is there and a call_again link.
Default: 45
company_urlstring · uri
A company's website: its career site is scraped now (the company is added if unknown), e.g. https://www.example.com.
refreshboolean
true: scrape now even when the index already holds enough.
Enum values: truefalse
Default: false

Response 200 · application/json

Default layout. With schema=native the ai_ prefix is dropped and salary_raw / employment_type_raw hold the source's own text. Employer profile fields (org_industry, org_headcount…) come with include_basic_organization_details=true.

FieldTypeDescription
statusstringready (answered from the index), collecting (scraping launched, call again), collected (scraping finished within wait).
countintegerPostings in jobs.
jobsarray<Job>Postings, in the active-jobs layout.
requestsarray<object>What was launched: type (collect / company), id, status, status_url.
call_againstring | nullThe same search, to call when the scraping has finished.

Errors

400 a parameter is not understood (the message names it) · 404 no such endpoint · 429 slow down · 503 the query would scan too much: add a filter or a shorter window.