Read your jobs, candidates and applications, add candidates, let partners send candidates to you, and show your open jobs on your own site.
An admin opens Settings, then Integrations, then API keys, names the key and checks what it may do. The key is shown once, so copy it then. If the API isn't on for your organization, ask InsightHire support to turn it on. A key acts as the admin who made it: it sees only the jobs and candidates that person can see. You can revoke a key at any time.
Everything is JSON over HTTPS at https://api.insighthire.com/v1. Send your key in the Authorization header.
curl https://api.insighthire.com/v1/jobs?limit=10 \
-H "Authorization: Bearer ih_your_key_here"Each key can make 300 requests a minute. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. Past the limit you get a 429 and a Retry-After header.
List calls take limit (1 to 100, default 50), cursor, and updated_after (an ISO date, to fetch only what changed). To get the next page, pass the next_cursor from the last page as cursor. When next_cursor is null, you have it all. Dates are ISO 8601.
{
"data": [ { "id": "...", "title": "Registered Nurse", "updated_at": "2026-11-05T14:03:11.000Z" } ],
"next_cursor": "eyJ0IjoiMjAyNi0xMS0wNVQxNDowMzoxMS4wMDBaIiwiaSI6Ii4uLiJ9"
}Every error has the same shape, with a standard HTTP status: 400 for a bad request, 401 for a missing, wrong or revoked key, 403 when the key lacks access, 404 when something isn't found, and 429 when you're over the limit.
{ "error": { "code": "insufficient_scope", "message": "This API key does not have the candidates:write scope" } }Each one needs the access shown beside it.
GET/jobsjobs:read
List jobs. Filter by status, department_id, office_id.
GET/jobs/{id}jobs:read
One job.
GET/departmentsjobs:read
List departments.
GET/officesjobs:read
List offices.
GET/usersusers:read
List the people on your team.
GET/candidatescandidates:read
List candidates. Filter by email, job_id, kind.
GET/candidates/{id}candidates:read
One candidate.
POST/candidatescandidates:write
Add a candidate. A matching email returns the existing candidate instead of a copy.
PATCH/candidates/{id}candidates:write
Update a candidate.
GET/applicationsapplications:read
List applications. Filter by job_id, candidate_id, status.
GET/applications/{id}applications:read
One application.
POST/applicationsapplications:write
Put a candidate on a job.
POST/applications/{id}/moveapplications:write
Move an application to a status or stage.
POST/applications/{id}/rejectapplications:write
Reject an application, with an optional reason.
POST/ingestion/candidatesingestion
For partners: send a candidate for a job, with the source named.
If you send an email we already have, you get that candidate back with 200 and no copy is made. Send job_id to also put them on a job.
curl -X POST https://api.insighthire.com/v1/candidates \
-H "Authorization: Bearer ih_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "email": "sam@example.com", "first_name": "Sam", "last_name": "Rivera", "source": "Career fair" }'A partner uses a key with the ingestion access. Name the source and send your own external_id for the candidate. If you send the same external_id again, you get the first result back, so retries are safe.
curl -X POST https://api.insighthire.com/v1/ingestion/candidates \
-H "Authorization: Bearer ih_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "source": "Acme Staffing", "external_id": "cand-1042", "job_id": "JOB_ID",
"candidate": { "email": "sam@example.com", "first_name": "Sam", "last_name": "Rivera" } }'These need no key, so you can call them from a web page. They return only jobs you have published on your careers page. Use your careers page name as orgSlug.
GET/boards/{orgSlug}/jobs
The organization’s published open jobs. No key needed.
GET/boards/{orgSlug}/jobs/{id}
One published job, with its full description.
GET/openapi.json
This API as an OpenAPI 3 file.
curl https://api.insighthire.com/v1/boards/your-company/jobsLoad https://api.insighthire.com/v1/openapi.json into your API tool or code generator to get every endpoint, field and error.