SmartRecruiters Jobs API
Query jobs from SmartRecruiters boards through one API — and how its Posting API, custom fields and remote/hybrid booleans actually behave.
SmartRecruiters is a hiring platform aimed at growing and enterprise companies,
with boards at jobs.smartrecruiters.com/<Company>. It's the largest source in
this dataset at 216,791 postings — roughly three times LinkedIn — from 2,642
tracked boards. That ratio is the whole story of the platform: comparatively few
boards, each of them big. A source's size reflects how many companies use that
ATS and how reachable its boards are, not how good the postings are; read the
live number from /v1/meta rather than this
paragraph.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=smartrecruiters" \
--data-urlencode "time_frame=24h" \
--data-urlencode "limit=2"{
"data": [
{
"id": "smartrecruiters:744000041827391",
"title": "Restaurant General Manager",
"company": {
"slug": "vertex-hospitality",
"name": "Vertex Hospitality",
"domain": "vertexhospitality.com",
"website": "https://vertexhospitality.com",
"logo": "https://media.licdn.com/dms/image/…",
"industry": "Hospitality",
"employee_count": 8200
},
"location": {
"remote": false,
"countries": ["United States"],
"cities": ["Denver"],
"regions": ["Colorado"],
"raw": ["Denver, Colorado, United States"]
},
"employment_type": ["FULL_TIME"],
"work_arrangement": "On-site",
"seniority": "Mid-Senior level",
"salary": {
"min": 62000,
"max": 74000,
"currency": null,
"unit": "YEAR",
"annual_min": 62000,
"annual_max": 74000,
"summary": null
},
"skills": ["p&l", "scheduling"],
"taxonomies": ["Hospitality & Food Services"],
"apply_url": "https://jobs.smartrecruiters.com/VertexHospitality/744000041827391",
"url": "https://jobs.smartrecruiters.com/VertexHospitality/744000041827391",
"source": "smartrecruiters",
"posted_at": "2026-07-14T07:02:00.000Z",
"expires_at": null,
"updated_at": "2026-07-14T09:33:10.000Z"
}
],
"total": 2,
"limit": 2,
"offset": 0
}A null currency next to real min/max numbers isn't a bug — see the custom
fields section below.
How SmartRecruiters boards actually work#
A public Posting API, no auth, in two steps:
# 1. List — paginated, 100 per page, no descriptions
curl "https://api.smartrecruiters.com/v1/companies/<company>/postings?limit=100&offset=0"
# 2. Detail — one per posting, the description lives here
curl "https://api.smartrecruiters.com/v1/companies/<company>/postings/<id>"<company> is the identifier from jobs.smartrecruiters.com/<Company> — often
capitalised, like Visa. The list returns { content, offset, limit, totalFound }.
The description is assembled from jobAd.sections on the detail: jobDescription,
qualifications, additionalInformation and companyDescription, each a
{ title, text } pair. Read only jobDescription and you drop the entire
qualifications block — the field is populated, so nothing looks wrong.
The list is richer than most#
Before you pay for a single detail call, the list gives you location with
structured city / region / ISO country plus exact latitude and
longitude, typeOfEmployment, experienceLevel (in LinkedIn's vocabulary —
Mid-Senior Level, Entry Level), department, function, industry,
language, refNumber, and customField[].
Real coordinates straight from the provider are rare. Most platforms give you a string and you geocode it and hope.
Two remote flags, not one#
location.remote and location.hybrid are separate booleans, and together
they give the full three-way. Read only remote — the obvious move — and every
hybrid job loses its arrangement entirely. hybrid wins when set; otherwise
remote true or false maps to Remote or On-site.
Salary hides in two different places#
The detail carries a compensation object — { min, max, currency, period } —
when the employer sets one. But roughly 20% of boards publish pay in the list's
customField[] instead, even when compensation is empty. Surveyed across 30
boards on 2026-07-06.
Custom fields are employer-named, so there's no key to look for. You see
Salary Range, Pay Range, Salary for Advertising, and separate
Salary Min / Salary Max pairs. Matching them means matching labels, which
means a pile of near-misses that aren't the offered pay at all: Salary Grade,
Pay Classification, Bonus Eligibility, Loan Repayment, Payroll Country.
Each of those contains salary, pay or comp and none of them is a salary.
What bites you#
A numeric Min/Max pair carries no currency. When pay comes from
Salary Min: 62000 and Salary Max: 74000, the employer never said which
currency. Guessing USD is how a British board's salaries end up 30% too high in
your UI. We leave currency null and keep the numbers — a null currency next to
real numbers is honest; a wrong currency is not.
department is empty on most boards. Around 65% of boards leave it blank
while populating function. Falling back to function fills the column; promoting
function to team as well duplicates it. We fall back, and only keep function
as a distinct team when it differs.
fullLocation is worse than the structured fields. It's free text and often
sparse. Build from city + region + the ISO country resolved to a canonical
name and the country is reliable; use fullLocation only when there's nothing
else.
Pagination that stops early truncates a big board silently. Page size is 100
and boards here are large. Loop to a short page or offset + limit >= totalFound
— a fixed cap is a data bug that returns 200 every time.
`?source=` is exact and case-sensitive
The company identifier in the URL is capitalised — jobs.smartrecruiters.com/Visa.
The source value is not. ?source=SmartRecruiters returns zero rows and a
200, like every other wrong filter value on this API. It's
smartrecruiters, lowercase.
Or use ours#
SmartRecruiters is a straightforward platform with an expensive shape: a detail call per posting, across the largest posting count of any source here.
You get the description already assembled from all four jobAd sections, the
hybrid boolean read rather than dropped, salary recovered from customField[]
when compensation is empty and left currency-less rather than guessed, the
provider's own coordinates, and dedup against the same role appearing on
LinkedIn or a Greenhouse board — which
matters more here than anywhere, because ?source=smartrecruiters&limit=1 counts
jobs where SmartRecruiters won dedup, not jobs on SmartRecruiters. The dedup
guide has the mechanism.
SmartRecruiters is in the fast refresh tier, attempted every cycle. See coverage for the tiers and sources for why board count and posting count are close to unrelated.
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key