Async job status
Poll the status of an asynchronous job created by
AI match jobs or AI score interview
when called with "async": true.
Scope required: jobs:read
GET /api/v1/external/jobs/{job_id}
Authorization: Bearer sk_live_<key>
This endpoint counts towards the standard rate limit window (60 seconds).
Path parameters
| Parameter | Description |
|---|---|
job_id | The job_id returned in the async 202 Accepted response |
Example request
curl "https://api.oikohire.com/api/v1/external/jobs/extjob_abc123" \
-H "Authorization: Bearer sk_live_<key>"
Response 200 OK — job in progress
{
"status": "success",
"data": {
"job_id": "extjob_abc123",
"type": "match_jobs",
"status": "queued",
"result": null,
"error": null,
"created_at": "2026-07-10T09:00:00.000Z",
"updated_at": "2026-07-10T09:00:01.000Z"
}
}
Response 200 OK — job completed
{
"status": "success",
"data": {
"job_id": "extjob_abc123",
"type": "match_jobs",
"status": "completed",
"result": {
"matches": [
{
"job_id": "clx9job123abc",
"title": "Senior Backend Engineer",
"match_score": 0.87,
"rationale": "Matches 7/8 skills: typescript, postgresql, nestjs",
"skills_gap": {
"matched": ["typescript", "postgresql"],
"missing": ["kubernetes"]
}
}
]
},
"error": null,
"created_at": "2026-07-10T09:00:00.000Z",
"updated_at": "2026-07-10T09:00:08.000Z"
}
}
Job status values
status | Meaning |
|---|---|
queued | Job has been accepted and is waiting to be processed |
processing | Job is currently running |
completed | Job finished — result contains the payload |
failed | Job encountered an error — error contains the reason |
Polling strategy
A simple exponential back-off pattern avoids hammering the endpoint while delivering results promptly:
async function pollJobResult(apiKey, jobId) {
const url = `https://api.oikohire.com/api/v1/external/jobs/${jobId}`;
const headers = { Authorization: `Bearer ${apiKey}` };
let delay = 1000; // start at 1 s
for (let attempt = 0; attempt < 12; attempt++) {
await new Promise((r) => setTimeout(r, delay));
const res = await fetch(url, { headers });
const body = await res.json();
if (body.data.status === 'completed') return body.data.result;
if (body.data.status === 'failed') throw new Error(body.data.error);
delay = Math.min(delay * 1.5, 15_000); // cap at 15 s
}
throw new Error('Job timed out after 12 attempts');
}
Job expiry
Async jobs are retained for 24 hours from creation. After that, polling
the job ID returns 404 Not Found.
tip
For short transcripts or small resume texts, consider using the synchronous
mode (omit "async": true) to avoid the overhead of polling.