Clair reads a validated registry of employer boards in the background. Public
requests query Clair’s database only. They do not contact an employer site,
talk to an ATS, or fetch a caller-supplied URL.
That separation keeps request latency bounded by infrastructure Clair controls.
It also gives every result the same filters, pagination, freshness signals, and
error contract.
Base URL and authentication
The Jobs API is distributed through RapidAPI. Send your key and the Jobs API host on every request:Use the exact host shown on the RapidAPI listing. The News API is a separate
listing with a separate host, even when you use the same RapidAPI key.
What you can search
q is a case-insensitive substring filter over the posting title. It
determines which postings match; sort still controls their order. Use the
structured filters below for company, department, skills, compensation, and
other normalized fields.
Structured filters let you narrow the result set without parsing source text:
- Company, free-form location, and ISO 3166-1 alpha-2 country.
- Normalized
workplace_type:remote,hybrid, oronsite. - Derived
seniorityand careertrack. - Department or team.
- Skills requiring either every requested value with
skills_allor at least one withskills_any. - Compensation range, currency, and interval.
- Publisher time with
posted_afteror Clair discovery time withfirst_seen_after. - ATS provider and board identifier for advanced provenance filtering.
Jobs and internships share one resource
An internship is a posting, so it uses the same endpoint and schema as every other role. Set:q, country, workplace_type, skills, or discovery time:
The normalized job schema
Every result includes:- A stable Clair
id. title,company,department, andteam.- The primary
location, all publishedlocations, derivedcountry, and normalizedworkplace_type. - Source-provided
employment_type. - Validated HTTPS
posting_urlandapply_url; every returned posting has at least one, while either field can be null when the source exposes only the other. - Publisher timestamps, Clair discovery and verification timestamps.
- Normalized compensation with its extraction source.
- Derived
seniority,track,title_family, and canonicalskills. description_available, plus an optional 2,000-character plain-textdescription_excerpt.- Source provider, board, and external posting ID.
null when a source did not
state a value or it could not be derived safely. It does not invent an
employment type, country, salary, publication date, or company name. In
particular, a source board identifier is never substituted for a missing
company.
An indexed record with neither a valid HTTPS posting link nor a valid HTTPS
application link is omitted from search until a later crawl repairs it. It is
not presented as a closed job merely because one source response was
incomplete.
employment_type reflects what the source adapter could normalize. Some
publishers expose free-form values, so do not treat it as a closed enum.
Compensation semantics
Salary bounds use overlap matching:salary_min=150000keeps a posting whose stated maximum is at least 150,000.salary_max=200000keeps a posting whose stated minimum is at most 200,000.
currency is required whenever you send a salary bound. If you omit
salary_interval, bounds default to annual compensation. You can explicitly
filter year, hour, month, week, or day.
The nested compensation.source explains provenance:
Clair does not convert between currencies or silently annualize hourly pay.
Provenance and time
The timestamps answer different questions:
Use
posted_after for publication-date research. Use first_seen_after for
alerts or incremental discovery, because it remains available when a publisher
omits posted_at.
Each job also carries:
posting_url, apply_url, and
last_verified_at when auditing a result.
Index freshness
Every successful response includes anindex object inside meta:
as_of is the most recent successful board crawl recorded. It is not a claim
that every board was crawled at the same instant. stale_boards is the number
of enabled boards that have missed two of their own configured crawl intervals,
have never completed, or most recently failed.
Use per-job
last_verified_at when the exact freshness of one posting matters.
Cursor pagination
Pages are ordered newest first with a stable ID tiebreaker.sort=posted_at
uses the publisher time and falls back to first_seen_at when the publisher
supplied no date. sort=first_seen_at is useful for ingestion and alerting.
If meta.has_more is true, pass meta.next_cursor unchanged:
bad_cursor. Stop when has_more is false and
next_cursor is null.
Exact totals require an additional distinct-count query, so they are opt-in.
Set include_total=true to populate meta.total. Otherwise total is null and
total_is_exact is false.
Deduplication
One requisition can appear on several career sites owned by the same ATS tenant. Clair retains source rows for crawling, then applies provider-aware identity to search results. Workday uses tenant plus external requisition ID. Reviewed Recruitee aliases also require the same exact link, while a SmartRecruiters copy must agree on board, exact link, title, company, and location. Clair does not use fuzzy title similarity that could merge distinct openings. Optionalmeta.total counts canonical postings rather than storage
rows.
Description excerpts
Descriptions are excluded by default. Setinclude_description=true to return
description_excerpt, a plain-text preview capped at 2,000 characters.
The field is a preview, not a complete or archival copy. Follow posting_url
for the publisher’s current description.
Errors
Branch on the stableerror code. detail is human-readable and may change.
Validation failures return an array of details; typed failures return a string.
Origin responses include
X-Request-ID. Include it when reporting a problem.
Honor Retry-After on 503 responses and retry with backoff.