Skip to main content
Two search endpoints — quick keyword search vs. typed search with facets — plus a single-job lookup by id.
  • Quick searchGET /api/jobs. Simple query-string search with comma-separated filters. Best for lightweight integrations and URL-shareable queries.
  • Advanced searchPOST /api/jobs/search. Typed JSON body with inclusion/exclusion filters, range filters, and multi-value text queries. Best for filter UIs and programmatic search.
  • Get a jobGET /api/jobs/{id}. Re-fetch a single job by the id returned on any search or feed result. Free — deducts no credits.
All three return JobDto objects — see the Feed page for the full field reference.

Endpoints

Full request/response reference and a live “Try it” playground live on the dedicated pages below.

Quick search

GET /api/jobs — simple query-string search. Best for lightweight integrations and URL-shareable queries.

Advanced search

POST /api/jobs/search — typed JSON body with inclusion/exclusion filters, range filters, and multi-value text queries. Best for filter UIs and programmatic search.

Get a job

GET /api/jobs/{id} — fetch a single job by id (the id from any search or feed result). Free — deducts no credits.

Filter recipes

Basic text search with location

Search for jobs by keyword in one or more cities:
{
  "queries": ["data engineer"],
  "locations": ["Seattle", "Austin"],
  "page_size": 10
}
By default a query is a broad relevance search: each entry is matched against the job title, company name, popular skills, and summary, with typo tolerance. That maximises recall but means a query like data engineer can also surface roles whose title isn’t “data engineer” — the words appear elsewhere in the listing.

Title-scoped exact match (quoted phrases)

Wrap a query in double quotes to switch that entry to a strict match: the exact phrase must appear, contiguously, in the job title only. Typo tolerance and partial-word matching are turned off. Use this when the query is a job-title filter and broad matches are noise.
{
  "queries": ["\"Quantitative Developer\"", "\"Quant Developer\""]
}
Only jobs whose title contains “Quantitative Developer” (or “Quant Developer”) are returned; a “Senior Android Engineer” whose description mentions software won’t match. Multiple quoted entries are OR’d, so the example above returns titles matching either phrase. You can mix quoted and unquoted entries — each is evaluated independently and the results are combined:
{
  "queries": ["\"Quant Developer\"", "machine learning engineer"]
}
On GET /api/jobs the same rule applies to the q parameter — pass the quotes in the value (?q="Quantitative Developer").
A request may carry at most 5 positive terms in queries. Sending more returns a 400 (rather than silently ignoring the extras) so you always know exactly what was searched. Negative - exclusions don’t count toward the limit.

Skill include/exclude filtering

Find jobs requiring Python or Go but not PHP:
{
  "queries": ["backend developer"],
  "skills": {
    "include": ["python", "go"],
    "exclude": ["php"]
  }
}

Company filtering

Search only at specific companies, or exclude staffing agencies:
{
  "queries": ["product manager"],
  "companies": {
    "include": ["Google", "Meta", "Apple", "Amazon"]
  }
}
{
  "queries": ["software engineer"],
  "companies": {
    "exclude": ["Acme Staffing", "Generic Recruiting Co"]
  }
}

Salary range + experience level

Find senior or principal roles paying 150k150k–250k:
{
  "experience_levels": ["senior"],
  "salary_usd": { "min": 150000, "max": 250000 },
  "employment_types": ["full-time"]
}
For open-ended ranges, omit one bound:
{
  "salary_usd": { "min": 200000 }
}

Remote jobs posted recently

{
  "queries": ["machine learning engineer"],
  "work_models": ["remote"],
  "posted_after": "2026-02-01T00:00:00Z"
}

Bounded posting date window

Use posted_after / posted_before to bound results by the employer posting date.
{
  "queries": ["backend engineer"],
  "posted_after": "2026-02-01T00:00:00Z",
  "posted_before": "2026-03-01T00:00:00Z"
}

Full combination query

Combine every filter type for a highly targeted search:
{
  "queries": ["backend engineer", "platform engineer"],
  "locations": ["San Francisco", "New York", "Seattle"],
  "skills": {
    "include": ["go", "rust", "kubernetes"],
    "exclude": ["php", "wordpress"]
  },
  "companies": {
    "exclude": ["Acme Staffing"]
  },
  "work_models": ["remote", "hybrid"],
  "employment_types": ["full-time"],
  "experience_levels": ["senior", "lead"],
  "salary_usd": { "min": 150000, "max": 300000 },
  "posted_after": "2026-01-15T00:00:00Z",
  "posted_before": "2026-06-01T00:00:00Z",
  "page": 1,
  "page_size": 50
}

Selecting fields

By default every job carries all of its fields. To shrink the response, pass include_fields to keep only the non-core fields you actually need — the lightweight core fields (id, title, company, locations, compensation, dates, source, work-auth flags, …) are always returned.
include_fieldsResult
omitted / nullFull job — every field (the default, unchanged).
["description","benefits"]Core + description and benefits only.
[] (empty array)Core fields only.
The gateable non-core fields are description, summary, qualifications, responsibilities, and benefits. On GET /api/jobs pass a comma-separated string (?include_fields=description,benefits); on POST /api/jobs/search pass a JSON array. To get core fields only from the GET endpoint, send the empty value ?include_fields=. Unknown names are silently dropped, and any non-core field you don’t request comes back empty ("" / []) rather than absent — the same present-but-empty convention the facets use. The heavy description body dominates response size, so dropping it is the single biggest win for high-volume search.

Facets

The response includes a facets object with server-computed aggregations. The set of facets is controlled by the include_facets request parameter; when omitted the server returns a low-cardinality default subset to keep responses fast.

Available facets

Response keySource fieldNotes
work_modelwork_modelDefault
experience_levelexperience_levelDefault
employment_typeemployment_typeDefault
sourcesprovider_idDefault
industriescompany_industriesOpt-in — moderate cardinality
skillsall_skill_namesOpt-in — high cardinality, adds noticeable latency

Controlling the facet set

include_facetsResult
omitted / nullDefault subset (work_model, experience_level, employment_type, sources).
["skills"]Only skills is computed and returned.
[] (empty array)No facets — "facets": {}.
["skills","unknown"]skills is returned; unknown names are silently dropped.
On GET /api/jobs pass a comma-separated string (?include_facets=skills,industries); on POST /api/jobs/search pass a JSON array ("include_facets": ["skills", "industries"]). To skip facets from the GET endpoint, send the empty value ?include_facets=.

Example — default response

{
  "facets": {
    "experience_level": [
      { "key": "senior", "count": 4521 },
      { "key": "mid", "count": 3892 },
      { "key": "lead", "count": 1204 },
      { "key": "entry", "count": 987 },
      { "key": "executive", "count": 412 },
      { "key": "intern", "count": 43 }
    ],
    "work_model": [
      { "key": "remote", "count": 5230 },
      { "key": "hybrid", "count": 2847 },
      { "key": "onsite", "count": 1540 }
    ]
  }
}

Example — opting in to skills + industries

{
  "queries": ["backend engineer"],
  "include_facets": [
    "work_model",
    "experience_level",
    "employment_type",
    "sources",
    "industries",
    "skills"
  ]
}
Facet values for enum fields reflect the lowercased canonical values stored in the index, sorted by count descending. skills is faceted on its display-cased values. Counts are bounded by Typesense’s top_values strategy, so long-tail buckets may be approximate — exact totals come from the total field, not from summing facet counts. Use facet values to power filter UIs. Since all filter fields are case-insensitive, you can pass facet key values directly back as filter values.

Enum reference

Send the canonical value listed below. Filter inputs are matched case-insensitively and common variants (e.g. srsenior, WFHremote) are normalized server-side, so most reasonable strings will resolve to the right bucket.

work_models

ValueMeaning
remoteFully remote; no expectation of being in an office.
hybridMix of remote and in-office work.
onsiteOn-site / in-person at a specific location.

employment_types

ValueMeaning
full-timeStandard full-time permanent role.
part-timePart-time role with reduced hours.
contractFixed-term or contractor engagement (incl. contract-to-hire).
internshipInternship, co-op, or apprenticeship.
freelanceFreelance / self-employed / gig work.
temporaryShort-term or seasonal role.

experience_levels

ValueMeaning
internInterns, trainees, apprentices.
entryEntry-level / junior / new graduate.
midMid-level / intermediate individual contributor.
seniorSenior individual contributor (incl. staff, principal).
leadTech lead or first-line manager.
executiveDirector, VP, C-level, head-of.

Source values

All 57 ATS / job-board providers Jobo currently ingests. Use the provider_id in the sources filter (e.g. "sources": ["greenhouse", "lever"]); the same value comes back on the source field of every JobDto and in the facets.sources bucket.
provider_idProvider
adpmyjobsADP MyJobs
adpworkforcenowADP Workforce Now
applicantproApplicantPro
ashbyAshby
bamboohrBambooHR
breezyBreezy HR
careerplugCareerPlug
careerpuckCareerpuck
comeetComeet
csodCornerstone OnDemand
dayforceDayforce
doverDover
eightfoldEightfold
freshteamFreshteam
gemGem
gohireGoHire
greenhouseGreenhouse
hibobHiBob
hirebridgeHireBridge
hirehiveHireHive
hireologyHireology
hiringthingHiringThing
homerunHomerun
icimsiCIMS
isolvediSolved
jazzhrJazzHR
jobscoreJobScore
jobviteJobvite
joincomJoin.com
kulaKula
leverLever
manatalManatal
oraclecloudOracle Cloud
pageupPageUp
paycomPaycom
paycorPaycor
paylocityPaylocity
personioPersonio
phenompeoplePhenom
pinpointPinpoint
polymerPolymer
recootyRecooty
recruiteeRecruitee
ripplingRippling
rivalRival
smartrecruitersSmartRecruiters
successfactorsSAP SuccessFactors
taleoOracle Taleo
talnetTalNet (Oleeo)
teamtailorTeamtailor
trakstarTrakstar Hire
trinetTriNet
ultiproUltiPro (UKG Pro)
werecruitWeRecruit
workableWorkable
workdayWorkday
zohorecruitZoho Recruit