How the integration works
Your backend creates the interview. JobPilotNG prepares the competency framework and interview plan, returns a signed candidate URL, runs the session, and notifies your system when results are ready.
Send candidate, job and interview settings from your server.
Share the expiring interview URL with the candidate.
Process signed webhooks and retrieve the final report.
Authentication
All protected API requests use a server-side Bearer API key. Keep the key in your backend secret store; never expose it in browser code or a mobile application.
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonQuick start
Create a complete interview in one request. External IDs should be stable identifiers from your own database and are used to avoid duplicate candidate and job records.
curl --request POST \
--url https://interview.jobpilotng.com/api/v1/interviews \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"external_candidate_id": "candidate_1042",
"external_job_id": "job_287",
"candidate": {
"name": "Ada Okafor",
"email": "ada@example.com"
},
"job": {
"title": "Senior Backend Engineer",
"description": "Build secure Python APIs and distributed systems.",
"seniority": "senior",
"required_skills": ["Python", "PostgreSQL", "API design"],
"preferred_skills": ["Redis", "Docker"]
},
"settings": {
"duration_minutes": 25,
"difficulty": "adaptive",
"language": "en",
"voice": {
"accent": "nigerian",
"gender": "female",
"style": "professional",
"speed": 1.0
},
"record_audio": true,
"record_video": false
}
}'Successful response · 201 Created
{
"interview_id": "589ee26a-36ce-4f85-bc73-c83c49bc7797",
"status": "READY",
"interview_url": "https://interview.jobpilotng.com/i/…",
"expires_at": "2026-08-17T18:00:00Z"
}Create an interview
Required information
| Field | Purpose |
|---|---|
candidate.name, candidate.email | Identifies and contacts the participant. |
job.title, job.description | Builds the role-specific competency framework. |
settings.duration_minutes | 10–180 minutes; defaults to 25. |
settings.voice | Selects accent, gender, style and speed independently from scoring. |
Creating an interview performs AI role analysis and planning. It may take longer than a normal CRUD request. Treat a returned interview_id as the canonical identifier.
Interview lifecycle
The backend state machine—not the language model—controls every transition. Terminal states are COMPLETED and FAILED.
Transcripts, recordings and reports
COMPLETED. Scoring excludes accent and protected characteristics.Signed webhooks
Configure one HTTPS receiver to get lifecycle updates. Verify the HMAC signature against the exact raw request bytes before parsing JSON, then deduplicate using X-Webhook-Event-Id.
import crypto from 'node:crypto';
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SIGNING_SECRET)
.update(rawRequestBody)
.digest('hex');
const valid = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(request.headers['x-webhook-signature'])
);Events include interview.created, interview.started, interview.disconnected, interview.resumed, interview.completed, interview.failed, evaluation.completed, and report.generated. Failed deliveries retry with exponential backoff and retain the same event ID.
Errors and operational limits
| Status | Meaning | Action |
|---|---|---|
| 400 | Invalid operation | Check the requested interview action. |
| 401 | Missing or invalid API key | Correct the Bearer token. |
| 404 | Resource not found in your organization | Check the ID and API-key tenant. |
| 409 | State conflict or duplicate in progress | Fetch status before retrying. |
| 422 | Request validation failed | Inspect the structured validation response. |
| 429 | Rate limit exceeded | Retry with exponential backoff. |
| 502/503 | Provider or dependency unavailable | Retry transient failures safely. |
AI-backed endpoints are rate limited. Use idempotency/event IDs where provided and do not retry validation errors unchanged.