Jobvite Jobs API
Query jobs from Jobvite boards through one API with ?source=jobvite — plus how its /search endpoint really behaves, and why the board root lies about its size.
Jobvite is a recruiting platform used by mid-size and enterprise employers, and
its boards are the plain-HTML end of this pool: jobs.jobvite.com/<slug>, no JSON
API, no feed. There are 2,043 Jobvite postings in this dataset — a number that
moves hourly, so read it from /v1/meta rather than
trusting this sentence.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=jobvite" \
--data-urlencode "limit=2"{
"data": [
{
"id": "jobvite:altura_oXY3bfwT",
"title": "Staff Systems Engineer",
"company": {
"slug": "altura-systems",
"name": "Altura Systems",
"domain": "alturasystems.com",
"website": "https://alturasystems.com",
"logo": "https://media.licdn.com/dms/image/…",
"industry": "Software Development",
"employee_count": 5800
},
"location": {
"remote": false,
"countries": ["United States"],
"cities": ["San Jose"],
"regions": ["California"],
"raw": ["San Jose, CA"]
},
"employment_type": null,
"work_arrangement": null,
"seniority": null,
"salary": null,
"skills": ["kubernetes", "linux"],
"taxonomies": ["Software"],
"apply_url": "https://jobs.jobvite.com/altura/job/oXY3bfwT/apply",
"url": "https://jobs.jobvite.com/altura/job/oXY3bfwT",
"source": "jobvite",
"posted_at": "2026-07-13T11:20:44.000Z",
"expires_at": null,
"updated_at": "2026-07-14T11:20:44.000Z"
}
],
"total": 2,
"limit": 2,
"offset": 0
}Note that apply_url and url differ — Jobvite hangs the application form off
the posting path, which not every platform does. salary and employment_type
are null because the board's HTML carries neither; more on the dates below.
How Jobvite boards actually work#
Two GETs, no auth. The important part is which two:
# 1. List — /search, and ONLY /search. `p` is 0-INDEXED, 50 per page
curl "https://jobs.jobvite.com/<slug>/search?p=0"
# 2. Detail — one per posting; the body only exists here
curl "https://jobs.jobvite.com/<slug>/job/<id>"The board root shows a partial board and doesn't say so
jobs.jobvite.com/<slug> and <slug>/jobs/alljobs — the URLs a company links
from its own careers page, the ones a human would scrape — render part of
the board. One tenant shows 102 of its 202 postings. Another shows 0 of 64.
?p= is ignored on /jobs/alljobs, so paginating it gets you page one
forever. Only /search?p= is complete, and the server states the truth right
there in the markup: <div class="jv-pagination-text">1-50 of 202. Everything
returns 200 throughout.
p is 0-indexed, so a loop starting at 1 quietly drops the first fifty jobs.
page, pg, start and offset are all silently ignored and return page one.
It is not a JSON-LD board#
This is worth stating plainly, because Jobvite looks like it should be one and an early note in our own coverage docs said it was.
It isn't. Two tenants checked in detail — including a 200-posting board — carry
zero ld+json blocks, and a generic JobPosting extractor returns null on
them. Structured data exists on maybe a third of tenants. So HTML extraction is
mandatory here, and we don't use the JSON-LD path at all rather than run two code
paths that disagree with each other about the same board.
The practical consequence is on dates. The posting date exists only in the structured data, on the minority of tenants that ship it — the HTML carries none. Which brings us to:
What `posted_at` means on this source
Jobvite's HTML publishes no date, so posted_at
falls back to our first sight of the posting
rather than going null.
It's a sound ordering key and a sound "newer than X" filter. It is not a claim about when the employer published the role. If your product renders "posted 3 days ago" to an end user, know which sources can carry that sentence and which can't.
What bites you#
A bogus id returns 200 and the board shell. So does an id from another tenant. There's no 404 to catch, and an unknown tenant is worse: it returns 200 and Jobvite's own support page. The only reliable "this is really a job" signal is the description container itself — if it isn't there, you don't have a posting, whatever the status code says.
jv-job-detail-meta is variable-length. It's a run of segments joined by a
separator span, and tenants ship different runs: Dept | Loc | Req. Num. on one,
Dept | Loc on another, Loc alone on a third. Parse it positionally and the
third tenant's location becomes its department, on every posting, at 200. Take
the requisition number by its own label and the last remaining segment as the
location — that's the one segment every tenant has.
<h1> is the site name. The job title is <h2 class="jv-header">. Reach for
the <h1> out of habit and every posting on the board is named after the company.
The description container nests. A lazy match to the first </div> truncates
the body, so the div walk has to be balanced.
Or use ours#
Jobvite is small, and small platforms are where the effort-to-reward ratio is worst: the same class of problem as a big platform, spread across a fraction of the jobs.
You get the board enumerated through /search rather than the root that shows you
half of it, ids taken from a 0-indexed loop, descriptions from a balanced walk,
the location read by label rather than by position so a one-segment tenant doesn't
report its city as a department, the shell-page 200s rejected instead of stored as
empty jobs, and the company join.
And you get it deduplicated against the same role on LinkedIn or on another board — which on a source this size is a real share of the rows.
Refresh cadence varies by source; see coverage, and don't build anything that assumes uniform latency.
Query it with ?source=jobvite.
Quickstart · Pricing
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key