API Reference

Interviews

Create and manage interview records — CRUD endpoints with multi-tenant isolation.

Interview endpoints handle the full lifecycle of an interview record: creation, retrieval, status updates, plan management, and assessment access. All endpoints support both JWT authentication and API Key + X-Tenant-ID header authentication, and automatically scope results to the caller's tenant.

Endpoints

MethodEndpointPermissionDescription
POST/interviews/parse-resumeinterview:createExtract structured text from a resume file (PDF, DOCX, TXT)
GET/interviews/countsinterview:readGet interview counts grouped by status
POST/interviewsinterview:createCreate interview directly (admin UI)
GET/interviewsinterview:readList interviews with search, status filter, and pagination
GET/interviews/:idinterview:readGet single interview
PUT/interviews/:idinterview:updateUpdate interview fields
DELETE/interviews/:idinterview:deleteDelete interview record
POST/interviews/:id/conductinterview:conductStart live interview session
POST/interviews/:id/inviteinterview:updateGenerate candidate token and send invite email
POST/interviews/:id/assessinterview:assessDeprecated — assessment runs automatically
POST/interviews/:id/overrideinterview:updateApply recruiter override patch (add/remove skills, set role family)
GET/interviews/:id/overridesinterview:readGet all override patches for an interview

POST /interviews/parse-resume

Accepts a resume file (PDF, DOCX, or plain text) and returns clean extracted text suitable for pre-filling the interview creation form. Accepts multipart/form-data with a single file field.

bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/interviews/parse-resume \
  -H "Authorization: Bearer <jwt>" \
  -F "file=@/path/to/resume.pdf"
Response 200
{
  "resumeText": "Jane Smith\nSenior Software Engineer\n\nExperience:\n- 5 years TypeScript, React...",
  "originalLength": 4821
}
The extracted text is returned as-is for the caller to use. It is not persisted — paste it into the jobDescription or a candidate notes field when creating the interview.

GET /interviews/counts

Returns the count of interviews in each status for the authenticated tenant. Useful for dashboard summary cards.

bash
curl https://mayaapi.teamcast.ai/api/v1/interviews/counts \
  -H "Authorization: Bearer <jwt>"
Response 200
{
  "total": 142,
  "planned": 8,
  "approved": 94,
  "inProgress": 2,
  "infoNeeded": 3
}
approved includes both APPROVED and COMPLETED interviews so the dashboard card reflects all interviews that have passed the plan approval gate.

POST /interviews

Creates an interview record directly from the admin dashboard. External partner systems should use the Integration API (POST /integration/interviews) instead.

bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/interviews \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "candidateName": "Jane Smith",
    "candidateEmail": "jane@example.com",
    "position": "Senior Engineer",
    "level": "SENIOR",
    "skills": ["TypeScript", "React", "Node.js"],
    "jobDescription": "Build scalable platform services with modern tooling.",
    "scheduledAt": "2024-02-01T10:00:00.000Z"
  }'
Response 201
{
  "id": "interview-uuid",
  "tenantId": "tenant-uuid",
  "candidateName": "Jane Smith",
  "candidateEmail": "jane@example.com",
  "position": "Senior Engineer",
  "level": "senior",
  "skills": ["TypeScript", "React", "Node.js"],
  "duration": 45,
  "status": "planned",
  "workflowState": null,
  "planId": null,
  "sessionId": null,
  "runId": null,
  "createdAt": "2024-01-15T10:00:00.000Z",
  "updatedAt": "2024-01-15T10:00:00.000Z"
}
Normalization runs synchronously at creation time. Skills are canonicalized (e.g. ReactJS becomes React), the resume is parsed for claimed and evidenced skills, and the role is classified into a roleFamily. All artifacts are stored and visible on the GET /interviews/:id response. Taxonomy enrichment for unknown roles and skill graph edges runs asynchronously in the background.

GET /interviews

Returns a paginated list of interviews for the authenticated tenant. Supports full-text search across candidate name, position, and email, plus filtering by workflow status.

bash
# List with pagination
curl "https://mayaapi.teamcast.ai/api/v1/interviews?page=1&limit=20" \
  -H "Authorization: Bearer <jwt>"

# Search by name or position
curl "https://mayaapi.teamcast.ai/api/v1/interviews?search=Jane&status=PENDING" \
  -H "Authorization: Bearer <jwt>"
Query ParamTypeDefaultDescription
pagenumber1Page number (1-indexed)
limitnumber20Items per page (max 100)
statusstring-Filter by workflow status (e.g. PENDING, COMPLETED, IN_PROGRESS)
searchstring-Search candidate name, email, or position
Response 200
{
  "data": [
    {
      "id": "interview-uuid",
      "candidateName": "Jane Smith",
      "candidateEmail": "jane@example.com",
      "position": "Senior Engineer",
      "level": "senior",
      "skills": ["TypeScript", "React"],
      "duration": 45,
      "status": "planned",
      "workflowState": "pending",
      "planId": "plan-uuid",
      "sessionId": null,
      "runId": "agno-run-uuid",
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z"
    }
  ],
  "total": 47,
  "page": 1,
  "limit": 20,
  "totalPages": 3
}

GET /interviews/:id

Returns the full interview record including all fields.

bash
curl https://mayaapi.teamcast.ai/api/v1/interviews/interview-uuid \
  -H "Authorization: Bearer <jwt>"
Response 200
{
  "id": "interview-uuid",
  "tenantId": "tenant-uuid",
  "candidateName": "Jane Smith",
  "candidateEmail": "jane@example.com",
  "position": "Senior Engineer",
  "level": "senior",
  "skills": ["TypeScript", "React", "Node.js"],
  "duration": 45,
  "status": "planned",
  "jobDescription": "Build scalable platform services...",
  "workflowState": "pending",
  "runId": "agno-run-uuid",
  "planId": "plan-uuid",
  "sessionId": null,
  "callbackUrl": "https://ats.example.com/webhook",
  "candidateClaimedSkills": ["React", "TypeScript", "Node.js"],
  "candidateEvidencedSkills": ["React", "TypeScript"],
  "candidateDemonstratedSkills": ["React", "TypeScript"],
  "canonicalPayload": {
    "skills": ["React", "TypeScript", "Node.js"],
    "jobDescription": "Build scalable platform services...",
    "candidateResume": "Jane Smith...",
    "roleFamily": "frontend_engineering",
    "roleCategory": "engineering",
    "relatedSkills": ["Next.js", "Redux", "GraphQL"]
  },
  "diffReport": { "skills[0]": { "before": "ReactJS", "after": "React" } },
  "rawPayload": { "position": "Sr Engineer", "skills": ["ReactJS", "TS", "Node.js"] },
  "createdAt": "2024-01-15T10:00:00.000Z",
  "updatedAt": "2024-01-15T10:45:00.000Z"
}
See Input Normalization for a full explanation of normalization artifacts.candidateDemonstratedSkills is written by the assessor agent after the interview completes — it contains skills scored 2 or higher in the assessment.canonicalPayload.roleFamily and roleCategory are set by the AI taxonomy enricher and drive competency selection in the planner.canonicalPayload.relatedSkills are adjacent skills discovered via the capability graph.

POST /interviews/:id/conduct

Creates a live interview session for an approved interview. Called internally when the candidate starts their session. Returns a sessionId used for the WebSocket connection.

bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/interviews/interview-uuid/conduct \
  -H "Authorization: Bearer <jwt>"
Response 201
{
  "sessionId": "session-uuid",
  "interviewId": "interview-uuid",
  "status": "created"
}

POST /interviews/:id/invite

Generates a signed candidate access token for the interview and sends an invitation email to the candidate. If a token already exists for the interview, the existing token is reused (so the link stays stable). Returns the interview link and whether the email was delivered.

RequirementDetail
candidateEmailMust be set on the interview record before calling this endpoint
Token expiry7 days from generation (configurable via CANDIDATE_TOKEN_EXPIRY_DAYS)
EmailSent from the configured SMTP sender — brandless candidate layout
bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/interviews/interview-uuid/invite \
  -H "Authorization: Bearer <jwt>"
Response 200
{
  "interviewLink": "{YOUR_APP_URL}/interview/join/abc123token",
  "token": "abc123token",
  "emailSent": true
}
If the candidate already has a link, calling /invite again reuses the same token — the link does not change. Use this to resend without invalidating an existing link.

POST /interviews/:id/assess

This endpoint is deprecated and will throw a 400 Bad Request. The Assessor Agent runs automatically via Kafka when the interview session ends — no manual trigger is needed. To retrigger a failed assessment, use the POST /a2a/interview/:id/retrigger-assessment endpoint.

Do not call this endpoint. Assessment is triggered automatically by theinterview.completed Kafka event and is handled by the Assessor Agent at port 7779. The admin UI retrigger button uses the A2A retrigger endpoint instead.

Error Responses

404 Not Found

json
{
  "statusCode": 404,
  "message": "Interview not found"
}

403 Forbidden

json
{
  "statusCode": 403,
  "message": "Insufficient permissions. Required: interview:read"
}
Interviews created via the Integration API (POST /integration/interviews) are also accessible via these endpoints using their id.
Was this page helpful?