iSolved Hire Jobs API
Query jobs from iSolved Hire boards through one API with ?source=isolved — plus how iSolved Hire's core jobs endpoint really behaves.
iSolved Hire is the recruiting module of isolved, an HCM suite sold to small and
mid-sized US employers. Boards live at <tenant>.isolvedhire.com.
The useful thing to know about this platform is that it is not really its own platform. iSolved Hire is ApplicantPro white-labelled — same endpoints, same JSON envelope, same field names, same quirks, on a different hostname. One implementation backs both, and a fix to the shape fixes both at once. If you have read the ApplicantPro page, you have read this one; the only things that differ are the host and the tenant namespace.
That is worth stating plainly because from the outside they look like two integrations to build. They are one.
How iSolved Hire boards actually work#
Three steps, identical to ApplicantPro's with isolvedhire.com swapped in:
# 1. Bootstrap — the board HTML is the only place `domainId` exists
curl -L "https://<tenant>.isolvedhire.com/jobs/" # → componentData: { domainId : 4689 }
# 2. List — every live posting, no descriptions
curl -L "https://<tenant>.isolvedhire.com/core/jobs/<domainId>?getParams=%7B%7D"
# 3. Detail — the body, plus a benefits block
curl -L "https://<tenant>.isolvedhire.com/core/jobs/<domainId>/<jobId>/job-details?getParams=%7B%7D"The list carries salary (minSalary/maxSalary with payTypeFrame as the unit),
employmentType, workplaceType, a structured location and
startDateRef/endDateRef. It carries no description, so the body is one detail
call per posting.
On the tenant we tested, that returned 49 jobs with 49 descriptions — a small board, fully readable, which is the profile of this platform generally.
The two traps come with it#
`getParams` is required, and omitting it returns 200
Leave getParams off and the API answers HTTP 200 carrying a PHP type error
in the body (Argument 1 passed to Awesome\Utils\… must be of the type array, null given). A status check sails straight past it: successful request, empty
list, a board that looks like it isn't hiring. getParams={} — url-encoded,
%7B%7D — satisfies it.
domainId cannot be derived from the slug. It exists only in the board HTML,
as componentData: { domainId : 4689 }, which is why the bootstrap fetch is a
required step rather than an optimisation. Churned tenants redirect to
/notset.php and yield no domainId, which is at least a clean liveness signal.
orgTitle is not the employer. It's the internal org unit — "Airport",
"Data", "Library -Dept #4100" — and mapping it to a company name writes
nonsense into your dataset as an employing entity. It belongs in team.
untilFilled makes endDateRef a placeholder, not a deadline. Expire on it
and you drop live jobs.
Or use ours#
A bootstrap fetch for a domainId that exists nowhere but the board HTML, a list
call whose missing parameter answers 200 with a PHP type error in the body, and
a detail call per posting.
You get the domainId bootstrap handled per tenant, getParams always present,
descriptions and the benefits block, salary with the unit read off
payTypeFrame, orgTitle filed as a team rather than libelling "Data" as an
employer, untilFilled postings left unexpired, churned tenants reaped off the
/notset.php redirect, ids scoped per tenant, and the company
join. One implementation carries all of that for both
hostnames at once.
Query it with ?source=isolved, on the same Job shape as
everything else on /ats. The white-label original is
?source=applicantpro: the same shape over different tenants, so it's a second
source value rather than a second way of asking for these rows. Both keys, and
whatever else ?source= accepts at the moment you read it, come from sources on
/v1/meta. Quickstart, then
pricing.
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key