Skip to content

Lifecycle

Every interview moves through three phases described in the following diagram.

┌──────────────┐        ┌──────────────────┐        ┌─────────────┐
│  YOUR APP    │        │   Allps API      │        │  CANDIDATE  │
└──────┬───────┘        └────────┬─────────┘        └──────┬──────┘
       │                         │                         │
       │  PHASE 1 — SCHEDULE     │                         │
       │                         │                         │
       │  POST /interview/       │                         │
       │  create-from-questions  │                         │
       ├────────────────────────►│                         │
       │                         │                         │
       │                         │  • Persist record       │
       │                         │  • Generate questions   │
       │                         │  • Hash payload         │
       │                         │                         │
       │◄────────────────────────┤                         │
       │  { interview_id,        │                         │
       │    interview_link }     │                         │
       │                         │                         │
       │                         │                         │
       │  PHASE 2 — DELIVERY (out-of-band)                 │
       │                         │                         │
       │  interview_link         │                         │
       ├───────────────────────────────────────────────────►
       │                         │                         │
       │                         │  Candidate opens link,  │
       │                         │  grants mic access      │
       │                         │◄───────────────────────►│
       │                         │                         │
       │                         │  Live AI-led interview  │
       │                         │  (audio / video stream) │
       │                         │◄───────────────────────►│
       │                         │                         │
       │                         │  • Persist transcript   │
       │                         │  • Persist evaluation   │
       │                         │  • Persist media        │
       │                         │                         │
       │                         │                         │
       │  PHASE 3 — RETRIEVE     │                         │
       │                         │                         │
       │  GET /interview/        │                         │
       │  details/{id}           │                         │
       ├────────────────────────►│                         │
       │◄────────────────────────┤                         │
       │  state = 2 (ENDED)      │                         │
       │                         │                         │
       │  GET /interview/        │                         │
       │  transcript/{id}        │                         │
       ├────────────────────────►│                         │
       │◄────────────────────────┤                         │
       │                         │                         │
       │  GET /interview/        │                         │
       │  evaluation-report/{id} │                         │
       ├────────────────────────►│                         │
       │◄────────────────────────┤                         │
       │                         │                         │

Phase 1 — Scheduling an interview

Three create endpoints cover the three kinds of interview the platform supports.

Endpoint Interview kind Evaluation shape
POST /interview/create-from-questions Job/Skill interview Per-question rating + LLM overall summary.
POST /interview/screening/create-from-questions Screening interview Boolean qualifying outcomes + communication analysis.
POST /interview/create-from-questions with interview_type: 2 Video introduction No evaluation; media hand-off only.

These endpoints return an interview_id and an interview_link.

1.1 Job interview from structured questions

POST /interview/create-from-questions
Request body
{
  "job_title": "Senior Backend Engineer",
  "candidate_id": "0f2b8c6e-4c9b-4d1a-9b2f-0f2b8c6e4c9b",
  "language_code": 1,
  "experience_level": "senior",
  "difficulty_level": "medium",
  "primary_tech_focus": "Distributed Systems",
  "questions": [
    {
      "question": "Walk me through how you would design a rate limiter.",
      "evaluation_criteria": [
        "Mentions token bucket or sliding window",
        "Discusses distributed state (Redis, etc.)",
        "Considers burst vs sustained traffic"
      ],
      "sample_answer": "A token bucket with a Redis-backed counter is common…",
      "type": "technical"
    }
  ]
}

Field reference — CreateInterviewFromQuestionsRequest

Field Type Required Notes
job_title string yes Displayed to the candidate.
candidate_id string yes Your internal ID. Echoed back on every read so you can correlate.
language_code integer no (default 1) Language Allps speaks and evaluates in. See AgentLanguages.
questions array of SkillInterviewQuestion yes The question list.
questions[].question string yes The literal question text.
questions[].evaluation_criteria string[] yes What "good" looks like. Give the LLM concrete, checkable bullets.
questions[].sample_answer string | null no Optional model answer the evaluator can reference.
questions[].type "technical" | "behavioral" | "situational" no (default "technical") Governs the evaluator's rubric.
experience_level "junior" | "senior" | "assistant" | "intern" no (default "junior") Calibrates follow-up difficulty.
difficulty_level "easy" | "medium" | "hard" no (default "easy") Further tunes question selection.
primary_tech_focus string yes Free-text domain label used in prompts.
{
  "message": "Interview created successfully",
  "interview_id": "0f2b8c6e-4c9b-4d1a-9b2f-0f2b8c6e4c9b",
  "interview_link": "https://sandbox.tara.allps.ai/interview?iid=0f2b8c6e-…"
}
{
  "detail": [
    {
      "loc": ["body", "questions"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

1.2 Screening interview from structured questions

Screening interviews have a different evaluation process. Every question is either graded against explicit criteria (qualifying) or recorded without grading (information). The response also includes a communication analysis (filler words, repetition, clarity).

POST /interview/screening/create-from-questions
Request body — ScreeningInterviewATSCreateRequest
{
  "job_title": "Customer Support Lead",
  "candidate_id": "0f2b8c6e-4c9b-4d1a-9b2f-0f2b8c6e4c9b",
  "interview_lang_code": 1,
  "questions": [
    {
      "question_text": "Are you legally authorized to work in the EU?",
      "question_type": "qualifying",
      "asking_order": 1,
      "qualifying_criteria": "A clear yes/no answer. 'Yes' is the expected outcome."
    },
    {
      "question_text": "What is your current notice period?",
      "question_type": "information",
      "asking_order": 2,
      "qualifying_criteria": null
    }
  ]
}

Field reference — ScreeningQuestionSchema

Field Type Required Notes
question_text string yes Question text.
question_type "qualifying" | "information" yes Qualifying questions are graded. Information questions are only recorded.
asking_order integer yes Position in the interview. Use 1, 2, 3, …
qualifying_criteria string | null yes (may be null) Grading rubric for qualifying questions. Ignored for information questions.

Language field name

The screening endpoint takes interview_lang_code, not language_code. The values are the same (AgentLanguages).

1.3 Resetting an interview

Development and staging only. Wipes the transcript, evaluation, state details and any local media so the same interview can be retaken.

POST /interview/reset/{interview_id}
{
  "success": true,
  "message": "interview reset. You can retake it"
}

In production, this endpoint returns OperationNotPermittedException.

No idempotency on create

Create endpoints are not idempotent. If you retry a create after a network timeout you may create a duplicate interview. See Idempotency for the recommended retry strategy.


Phase 2 — The candidate experience

This phase happens entirely on Allps.

2.1 What the candidate sees

  1. The candidate opens /interview?iid=….
  2. The AI greets them, asks for a self-introduction, and walks through the question set — adapting follow-ups based on their answers.
  3. When all questions are asked, interview is concluded.

2.2 Constraints to communicate

Important information for the candidates

These constraints trip up some candidates who aren't informed ahead of time. Put a one-line note next to the link when you send it.

  • One active session per interview. If the interview is already open in another tab or device, the new connection is rejected with an INTERVIEW_NOT_ALLOWED event. The candidate must close the old session first.
  • Microphone permission is required. Allps cannot conduct the interview without it.
  • Interruptions are tolerated for a limited grace period. If the candidate disconnects and returns, their state is preserved for maximum of 15 minutes. After that, the interview is terminated with reason masked as user-inactivity.

Phase 3 — Retrieving results

Once the candidate finishes, the interview record transitions to state == 2 (ENDED). You then have two choices: poll the read endpoints, or register a webhook and have results pushed to you.

Recommended only if you have a small number of interviews or want to avoid owning a receiver.

  1. Call GET /interview/details/{id} every 30–60 seconds.
  2. Stop when state == 2.
  3. Fetch the evaluation report. If it returns 404 InterviewNotEndException, wait 30 seconds and try again — the report is generated asynchronously and may lag a few seconds behind the state transition.
  4. Fetch the transcript. Recordings may be delayed further — they are remuxed and uploaded to cloud storage in the background.

Backoff: 30 s interval for the first 10 minutes, then 5 minutes for up to 24 hours, then give up.

curl https://sandbox.api.tara.allps.ai/interview/details/0f2b8c6e-… \
  -H "x-application-secret-key: sk_int_your_key_here"

Recommended for production. See the Webhooks page for the full setup, but the short version is:

  1. POST /webhooks/endpoints with your receiver URL.
  2. Store the one-time secret from the response.
  3. Verify the X-Webhook-Signature header on every delivery.
  4. The interview.media_processed event carries the transcript, the evaluation, and the recording URLs in a single payload.

3.1 Available artefacts

Artefact Endpoint Notes
Interview metadata GET /interview/details/{id} State, timing, language, ending reason.
Full transcript GET /interview/transcript/{id} Ordered list of turns with role and timestamp.
Question-level evaluation GET /interview/evaluation-report/{id} Short form for job interviews; long form for screening/video-intro.
Overall summary GET /interview/overall-evaluation-report/{id} Suitability verdict with strengths, weaknesses, recommendations.
Audio recording GET /interview/get-recording/{id} MP3, mixed candidate + agent audio.
Video recording GET /interview/get-video-recording/{id} WebM with video and mixed audio.
System logs GET /interview/get-logs/{id} Debug logs. Mostly for Allps support.

3.2 Reading the interview record

GET /interview/details/{interview_id} returns an InterviewDetailsResponse. The fields you'll use most often:

Field Meaning
id The interview_id you're already tracking.
state Runtime state — see InterviewState.
ending_reason Why the interview ended — see EndingReason.
language_code Language Allps conducted the interview in.
interview_type Numeric type code — see InterviewTypes.
archival_status Whether the recordings have been processed and uploaded.
created_at Timestamp of interview creation.
allpsai_interview_id Upstream id when the interview originated from the Talent platform.

3.3 Reading the transcript

GET /interview/transcript/{interview_id} returns an InterviewTranscriptResponse:

{
  "transcript": [
    {
      "role": "assistant",
      "content": "Hello! I'm Allps, your AI interviewer for today. Welcome!",
      "created_at": "2025-01-15T10:00:01.234Z",
      "control_id": "procedural",
      "video_time": { "begin": 0, "end": 8, "formatted": "00:00 - 00:08" }
    },
    {
      "role": "user",
      "content": "Hi, thanks for having me. I'm a backend engineer with about eight years of experience.",
      "created_at": "2025-01-15T10:00:22.101Z",
      "control_id": "procedural",
      "video_time": { "begin": 8, "end": 27, "formatted": "00:08 - 00:27" }
    }
  ]
}
  • role is "user" (the candidate) or "assistant" (the AI).
  • control_id links each turn to the specific question it belongs to (matching the ids used in the evaluation report). Turns with control_id = "procedural" are greetings, transitions, or acknowledgements that aren't scored.
  • video_time gives begin/end offsets in seconds — use it to deep-link a video player directly to a turn.

3.4 Reading the evaluation

The response shape depends on interview_type.

Returns an OverallEvaluation — the short form:

{
  "overall_assessment": {
    "suitability": "Meets expectations",
    "strengths": [
      "Strong grasp of distributed systems fundamentals",
      "Clear, structured communication"
    ],
    "weaknesses": [
      "Limited exposure to large-scale data pipelines"
    ],
    "recommendations": [
      "Probe deeper on data engineering experience in a follow-up round"
    ]
  }
}

suitability is always returned in English, so you can safely switch on it regardless of the interview language. Values are enumerated in Suitability.

Returns an InterviewEvaluationReportResponse — the full report:

{
  "id": "…",
  "interview": "…",
  "user": "…",
  "evaluation_report": { "questions": [ /* … */ ] },
  "overall_evaluation": null,
  "video_analysis_report": null,
  "comm_analysis_report": { /* … */ },
  "created_at": "2025-01-15T10:05:00Z"
}

The per-question breakdown lives under evaluation_report.questions. Each entry matches the EvaluatedQuestion schema in the API Reference.

3.5 Reading the overall summary

GET /interview/overall-evaluation-report/{interview_id} always returns the short OverallEvaluation form, regardless of interview_type. Use it when you only need the verdict and don't want to branch on interview kind.

3.6 Recordings

{ "interview_recording": "<presigned-url>" }

Do not persist the recording URL

The presigned URL is short-lived (typically one hour). Store the interview_id, not the URL, and re-request when you need the file. If you must archive the bytes, download them within the validity window.

If a recording isn't ready yet — the interview just ended, or archival is still in progress — you may receive an HTTP 500 RecordingCreationException. Retry with exponential backoff. Poll archival_status on the details endpoint if you want to know when it's safe to fetch.