roleset.

144,912 open roles 19,182 companies 27,172 boards 6 ATS platforms

Job postings API · REST + MCP

One query, every ATS-hosted job, with what changed since yesterday.

Roleset crawls official public ATS feeds — Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Personio, Workable, Workday and Teamtailor — normalizes every posting into one schema, and records every change as an event. You get the index, not a scraper.

Change feed GET /v1/jobs/changes?since=…
Each event once. Follow meta.next_cursor — no gaps, no repeats. sample

First call, three ways

No SDK required. JSON in, JSON out, cursor pagination, RFC 7807 errors. /stats and /schema are free and need no key.

# Every engineering role opened in the last 24 hours
curl -H "Authorization: Bearer $ROLESET_KEY" \
  "https://api.roleset.io/v1/jobs/changes?event=opened&department=Engineering"

# Remote backend roles in Germany
curl -H "Authorization: Bearer $ROLESET_KEY" \
  "https://api.roleset.io/v1/jobs/search?q=backend&remote=true&country=DE"

# Is this company growing, and where?
curl -H "Authorization: Bearer $ROLESET_KEY" \
  "https://api.roleset.io/v1/companies/acme.com/hiring-signal"

Seven, and one of them is the point

/jobs/changes is what separates this from a list of feed URLs. Poll it instead of re-running a search and diffing the results yourself.

EndpointWhat it answersBilled
GET /jobs/changes Everything that opened, changed, closed or reopened since your cursor, with a diff of the fields that moved. per event
GET /jobs/search Keywords, title, company, city, country, remote, ATS, department, employment type, posting date. per record
GET /jobs/{id} One posting with its full description. 1 record
GET /companies/{id}/jobs Every open role at one company, by domain, board slug or name. per record
GET /companies/{id}/hiring-signal Open roles by department, with 7- and 30-day deltas. 1 call
GET /stats Index size and freshness. free
GET /schema JSON Schema of the job record. free

One schema across nine platforms

Nine ATS platforms disagree about almost everything. Normalizing that disagreement is the work you are paying not to do.

Titles

Sr. Backend Engineer (m/w/d) #4412 and Senior Backend Engineer — Berlin both normalize to senior backend engineer. Gender markers, requisition ids and location suffixes come off.

Locations

Free text becomes {city, region, country, remote}. Hybrid (Vancouver, British Columbia) resolves to a city, a province and CA.

Salary

Structured to {min, max, currency, interval} when the board publishes one. CA$45/hour is CAD, not USD. When the string says "competitive", the fields stay null rather than guessing.

Duplicates

One company running two boards yields one live record. The newest wins; the other keeps a superseded_by pointer so nothing disappears.

Every active board, inside 24 hours

And we tell you when. Every response carries meta.last_crawled_min — the oldest successful crawl behind the exact rows you were handed, so you can caveat an answer instead of guessing at it.

PlatformBoardsOrigin
Greenhouse6,720boards-api.greenhouse.io
SmartRecruiters5,811api.smartrecruiters.com
Personio4,724*.jobs.personio.com
Ashby3,890api.ashbyhq.com
Recruitee3,417*.recruitee.com
Lever2,610api.lever.co

Pay for what you pull

A record is one job posting, or one change event, returned to you. /stats and /schema are free and need no key.

PlanIncluded each monthBeyond thatPrice
Free 500 records Requests stop; nothing is charged $0 · no card
Starter 50,000 records $2.00 per 1,000 $49 / month
Growth 500,000 records $1.00 per 1,000 $199 / month
Higher volume Tell us what you need — talk to us

Prices exclude sales tax and VAT. Paddle is the merchant of record and adds them at checkout where they apply, so a US or EU card sees a little more than the figure above.

No surprise bills

We email you at 80% and 100% of your included records. Overage is billed in arrears on your next invoice, so you see it before you pay it — and it is never charged unless you agreed to the rate.

A ceiling, not a cliff

Every account has a monthly limit that stops requests outright, so runaway automation cannot run up an unbounded bill. Going over your included records does not interrupt anything.

30-day money back

Not what you need? Email us within 30 days of a subscription payment and we refund it, no explanation required. See the refund policy.

No signup form

Take a free key below — no account, no email, no card. We store a hash of the key and nothing else about you. For a paid plan, email index@roleset.io and we set it up within a working day — your key keeps working while we do.

Take a free key

500 records a month. It is issued the moment you ask, and shown once — we keep only a hash of it, so we cannot resend it.

The index has edges, and they are on purpose

  • No personal data. No applicants, no recruiter names, no contact details. Email addresses and phone numbers are stripped from descriptions before anything is written down.
  • No aggregators. Official public ATS endpoints only. No LinkedIn, no Indeed, no HTML scraping.
  • No inferred fields. Seniority and skills are not guessed at. If a board does not publish a salary, the salary is null.
  • A posting can close between crawls. Freshness is a 24-hour guarantee, not a live socket. last_crawled_min tells you where you stand.