Search open roles across companies

Flat, role-granular job search: the individual open roles across companies matching function / geo (country) / since (first-seen lower bound), one row per logical req. LinkedIn-excluded: ATS tenants plus public job boards and aggregators; each row's board names its source. since and first_seen are our first observation of the req, not the employer's posting date. Freshness-floored, PK-ordered and keyset-paginated via the opaque next_cursor (the page's last company_id:req_key). The company-granular reverse view is /v1/reqs/search; full multi-board dedup for one company is /v1/companies/{company_id}/open-reqs.

industry, industry_terms and headcount_band cut the corpus down to your ICP's companies. Repeat a parameter to OR its values; different parameters AND. They are filters only -- no company facet is added to a served row by passing one -- and a company whose fact we do not hold is never matched, so a cut is honestly narrow rather than quietly padded.

exclude_employer_types drops roles whose posting is classified as a given employer type (e.g. staffing), keeping unclassified ones unless 'unknown' is listed. Opt-in: omit it and the page is unchanged.

desc_q keeps only roles whose description contains the keyword or phrase (words match adjacent, in order). It filters; it never ranks, and it combines with q, function and the other filters by AND.

q is free-text title search, ranked: it expands semantically to nearby job titles and matches them against the posting's own title, and each row carries the relevance (0-1) it scored. sort picks the ordering -- 'relevance' (the default whenever q is given) or 'recency'. Omit both and the page keeps its shipped stable order exactly. q is INDEPENDENT of function: pass both to search titles within one function.

An unresolvable function -- anything that is neither a function name nor a function taxonomy id -- is rejected with 422 instead of returning a silently-empty result. limit is bounded: an oversized page is rejected with 422 rather than truncated -- page through the full set with next_cursor instead of raising limit. The shared public demo key gets a tighter page instead -- it bills nothing, so no ledger-derived gate can bound it, and a full-size page would make a world-readable credential a bulk-export window onto the fresh index. sort='relevance' without a q, and a next_cursor replayed under a different sort, are 422s for the same reason: an order other than the one asked for reads as a measurement.

Requires the read scope.

get/v1/jobs/search

Request

  • Base URL: https://api.reqbeat.com
  • URL: https://api.reqbeat.com/v1/jobs/search
  • Auth: one of:
    • API key in header X-API-Key
    • HTTP bearer

Query parameters

functionstring nullable

Function to search for: its name as served in function_name, e.g. 'Software & IT', or its taxonomy id as served in function, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names, rather than returning a silently-empty result.

geostring nullable

Country name to restrict the search to, e.g. 'United States'. Matched against the geocoder's pinned country list.

sincestring date-time nullable

ISO-8601 timestamp lower bound on first_seen -- our first observation of the job, not the employer's posting date -- e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound.

qstring nullable

Free-text title search, e.g. 'senior backend engineer'. Expanded semantically to nearby job titles and matched against the posting's own title, with each row's relevance (0-1) reporting how well it matched. Independent of function: pass both to search titles WITHIN a function.

desc_qstring nullable

Keyword or phrase the job DESCRIPTION must contain, e.g. 'clay tables'. Words match as one adjacent phrase. A filter, not a ranking: it does not change relevance or the default order. A req whose description we have not resolved never matches, and a value with no searchable word is rejected with 422.

sortstring nullable

'relevance' (the default when q is given) or 'recency' (newest first_seen first). Omit without a q for the default stable order. 'relevance' without a q is rejected with 422 — there is no query to be relevant to.

source_type'ats_tenant' | 'board' nullable

Keep only reqs read from one kind of source: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Matches each req's source_type. Omit to search both, which is the default; any other value is rejected with 422.

exclude_agenciesboolean

Drop reqs whose company we have positively classified as a middleman — a staffing agency, job aggregator, subcontractor network or job board. A company whose kind we have not determined is KEPT, not dropped: this is a veto on proven intermediation, never a filter down to proven direct employers, so an unclassified company can never disappear from your results for want of a classification.

exclude_employer_typesstring[] nullable

Drop reqs whose own posting is classified as one of these employer types: 'direct', 'staffing', 'consultancy' or 'unknown'. Repeat to drop several, e.g. exclude_employer_types=staffing. Reads the posting, not the company (see exclude_agencies). A req we have not classified is KEPT unless 'unknown' is listed. Any other value is rejected with 422.

industrystring[] nullable

Company industry, matched exactly (case-insensitively), e.g. 'software development'. Repeat for an OR-set. The stored vocabulary is granular -- 'software development', 'computer software' and 'it services and it consulting' are three separate labels -- so prefer industry_terms unless you know the exact label you want. A company whose industry we do not hold is never matched.

headcount_bandstring[] nullable

Company size band: one of '1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001+'. Repeat for an OR-set. A band outside that ladder is rejected with 422 rather than answered emptily; a company whose headcount we do not hold is never matched.

industry_termsstring[] nullable

Substring of the company industry, matched case-insensitively, e.g. 'health' to reach both 'hospitals and health care' and 'health, wellness and fitness'. Repeat for an OR-set. The forgiving counterpart to industry, and usually the one to reach for first.

cursorstring nullable

Keyset pagination cursor: pass the previous page's next_cursor to get the next page. Omit for the first page.

limitinteger

Maximum jobs per page. An out-of-range value is rejected with 422 — page through the full set with next_cursor instead.

Headers

Idempotency-Keystring nullable

Response

Successful Response

next_cursorstring nullable required
as_ofstring date-time required

Changes

No recorded changes to this operation across all 1 revision of this API.