- Quick search —
GET /api/jobs. Simple query-string search with comma-separated filters. 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}. Re-fetch a single job by theidreturned on any search or feed result. Free — deducts no credits.
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: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.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 10 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:Company filtering
Search only at specific companies, or exclude staffing agencies:Salary range + experience level
Find senior or principal roles paying 250k:Remote jobs posted recently
Bounded posting date window
Useposted_after / posted_before to bound results by the employer posting date.
Full combination query
Combine every filter type for a highly targeted search:Selecting fields
By default every job carries all of its fields. To shrink the response, passinclude_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.
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 afacets 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
Controlling the facet set
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
Example — opting in to skills + industries
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.sr → senior, WFH → remote) are normalized server-side, so most reasonable strings will resolve to the right bucket.
work_models
employment_types
experience_levels
Source values
All 57 ATS / job-board providers Jobo currently ingests. Use theprovider_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.

