Find companies hiring for a role

Reverse who's-hiring-for {role, geo}: companies with active reqs matching q (posting title) / geo (country) / since (first-seen lower bound), deduped by company, each with its full hiring pulse and the specific reqs that matched. LinkedIn-excluded: ATS tenants plus public job boards and aggregators; each matched req's boards names its source. since and each req's first_seen are our first observation of the req, not the employer's posting date. Freshness-floored on the free tier only (by when a req was first seen), keyset-paginated via next_cursor (the last page's highest company_id).

q is a full-text query over the raw posting title, not an id: type the role the way a posting would spell it (staff engineer), every word must match -- plurals and other inflections included, so staff engineers is the same search -- and a title that matches nothing comes back as an empty page rather than an error. role is its deprecated former name, still accepted until its Sunset date. The two filters are deliberately asymmetric -- an unresolvable geo IS rejected with 422, because a country either is or is not in the stored vocabulary, whereas an unmatched title is an honest zero result.

geo, industry, industry_terms and headcount_band can each be repeated: repeat a parameter to OR its values; different parameters AND. Every other parameter takes one value, and repeating it is rejected with 422. industry, industry_terms and headcount_band cut the corpus down to your ICP's companies. They are filters only -- no company facet is added to the response 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.

limit is bounded: this endpoint meters the billed source_row atom off its own serialized rows, so an unbounded page is an unbounded invoice. An out-of-range limit is rejected with 422 rather than silently truncated; page through the full set with next_cursor. 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.

Requires the read scope.

get/v1/reqs/search

Request

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

Query parameters

qstring nullable

Full-text query over the raw posting title, e.g. 'staff engineer'. Every word must match, in any order, case-insensitively. Plurals and other inflections match, so 'engineers' finds 'engineer'. Omit to search every open req. A title that matches nothing returns an empty page rather than an error.

rolestring nullable

Deprecated former name of q, accepted until 2026-11-09 and answered exactly as q would be. A call that uses it carries Deprecation and Sunset response headers. Send q instead; sending both is rejected with 422.

geostring[] nullable

Country name to restrict the search to, e.g. 'United States'. Repeat it to search several countries at once. Matched against the geocoder's pinned country list; a country that cannot resolve is rejected with 422 rather than answered emptily.

sincestring date-time nullable

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

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 companies 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.

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.

cursorinteger nullable

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

limitinteger

Maximum companies 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_cursorinteger nullable required
as_ofstring date-time required

Changes

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