Human interviews
Your interviewers and the candidate on one call, inside your own product.
A human_interview is a call between the candidate and people on your side, with no
AI interviewer in it. It runs in the same embedded room as an ai_interview, and we
record it, transcribe it and write it up.
GET /v1/assessment-types lists it with its credit cost. It needs the Instant Meetings
module on your organization, which is on unless it has been turned off.
Create one
curl -X POST https://hiring-api.experthire.cloud/v1/assessments \
-H "Authorization: Bearer $EH_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"type": "human_interview",
"job_id": "'$JOB_ID'",
"candidate": { "email": "[email protected]", "name": "Jane Doe" },
"duration_minutes": 45,
"interviewers": [
{ "name": "Priya Shah", "external_id": "client-user-17" },
{ "name": "Sam Lee", "email": "[email protected]" }
]
}'
Still a placeholder: $EH_KEY, $JOB_ID. Add them under Your values above.
The response carries interviewers, each with the id you mint that person's session
with.
duration_minutesis 5 to 240, and 60 if you leave it out. It is the booked length and the countdown shown in the room. Nobody is cut off when it runs out.interviewerstakes up to ten people.nameis what the room and the transcript show.emailis optional and only stops the same person being added twice. We never email an interviewer.questionsandsend_inviteare refused on this type.
A job can have as many human interviews as you need, for the same candidate or different ones.
Change the people later with:
| Call | What it does |
|---|---|
GET /v1/assessments/{id}/interviewers | Everyone on your side, with joined_at once they joined |
POST /v1/assessments/{id}/interviewers | Add one, until the interview ends |
DELETE /v1/assessments/{id}/interviewers/{interviewer_id} | Remove one, and end their sessions |
Set a time
This step is optional. POST /v1/assessments/{id}/schedule with start_at and
time_zone books a slot, and calling it again reschedules. Each call emits
interview.scheduled or interview.rescheduled. See scheduling.
The time is a booking, not a lock: anyone with a session can join early. An interview
nobody joins is cancelled about an hour after its booked end, or seven days after creation if
it was never booked. POST /v1/assessments/{id}/cancel withdraws it yourself and refunds
the credit if nobody joined.
Put everyone in the room
Each person gets their own session. Mint the candidate's with the assessment alone, and
each interviewer's with their interviewer_id:
# The candidate
curl -X POST https://hiring-api.experthire.cloud/v1/sessions \
-H "Authorization: Bearer $EH_KEY" \
-d '{"assessment_id": "'$ID'", "origin": "https://app.example.com"}'
# One interviewer
curl -X POST https://hiring-api.experthire.cloud/v1/sessions \
-H "Authorization: Bearer $EH_KEY" \
-d '{"assessment_id": "'$ID'", "origin": "https://app.example.com", "interviewer_id": "'$INTERVIEWER_ID'"}'
Still a placeholder: $EH_KEY, $INTERVIEWER_ID. Add them under Your values above.
Mount every session with the loader, exactly as in embedding.
To send someone a hosted link instead, pass the same interviewer_id to
POST /v1/assessments/{id}/launch-link.
How the call behaves:
- Joining. Anyone can join while the interview is scheduled or in progress. The first person in starts it and, with a live key, starts recording everyone.
- Leaving is not ending. Anyone can leave and rejoin. The room sends your page
leftwhen they do. - Ending. An interviewer's End for everyone closes every room, and each one
sends your page
interview.endedwithendedBy. The candidate cannot end the interview. Your server can, withPOST /v1/assessments/{id}/endand your secret key. - Abandoned calls. If everyone leaves without ending, we end the interview 15
minutes after the last room checked in. The room checks in every 30 seconds while it
is open; if you build your own, poll
GET /v1/assessments/{id}/timerto do the same. Any interview still open four hours after it started is ended too. - No pause. The countdown keeps running while people step away.
What you get back
When the interview ends:
interview.endedfires.- Each person's room transcribed their own microphone during the call. Those lines are
put in order and saved, and
interview.transcript_availablefires. - We write a summary of the interview.
interview.summary_availablefires, andGET /v1/assessments/{id}/reportreturnssummary,interviewers,transcript_urland, on live,recording_url. - On live, the interview is scored.
interview.completedfires, and the report gainsscore,outcome,feedbackandsection_scores.
GET /v1/assessments/{id}/transcript labels each line Name [INTERVIEWER] or
Name [CANDIDATE]. Labels come from the session, not from the browser, so nobody can
speak under someone else's name. A person is not transcribed while their microphone is
muted.
GET /v1/assessments/{id}/recording-url returns one video of the whole call.
We send no email
Nothing goes out for a human interview: no invitation, calendar invite, reminder or completion email, to the candidate or to your interviewers. Our hosted booking page refuses one too. You own every message.
Sandbox
A sandbox human interview is not recorded and not scored. The transcript and summary are real, because the rooms still transcribe, and the report comes back once the summary is written.
Limits
- Up to ten interviewers per interview.
- Four hours per call.
- The embedded room has no shared code editor, whiteboard, chat or AI copilot for human interviews yet.