Integration API
HITL Workflow
Human-in-the-loop approval gates for data completion, plan review, and assessment verdicts.
The Human-in-the-Loop (HITL) workflow provides recruiter approval gates at three stages: data completion when interview information is incomplete, plan approval before the candidate receives their interview link, and assessment review after the interview concludes. All three stages are optional — configure autoApprovePlans: true in your tenant settings to run fully automated.
State Machine
RECEIVED
│
├── Data complete? ──────────────────► VALIDATING_SKILLS
│ │
└── Data incomplete? ──► INFO_NEEDED │
│ │ ▼
│ Recruiter GENERATING_PLAN
│ supplies │
│ missing data ▼
│ │ PENDING ─── Reject ──► REJECTED
└──────────────────┘ │
Approve / autoApprovePlans
│
▼
APPROVED
│
SCHEDULED ──► IN_PROGRESS ──► COMPLETED
│
ASSESSMENT_PENDING
│
┌───────────────┤
│ │
ASSESSMENT_APPROVED CANCELLEDAuto-Approve Mode
When autoApprovePlans is enabled on your tenant webhook config, the system skips the PENDING state entirely. As soon as the plan is generated, the interview is auto-approved, the candidate link is generated, and the interview.approved webhook fires — no manual recruiter action required.
| Setting | Effect |
|---|---|
| autoApprovePlans: false (default) | Interview enters PENDING state — recruiter must approve before candidate link is issued |
| autoApprovePlans: true | Plan is auto-approved — interview link issued immediately after plan generation |
autoApprovePlans is configured once per tenant in your account webhook settings. Contact your account manager to enable it.Stage 1: Data Completion
When a create request has missing or low-quality fields, the system enters INFO_NEEDED state and fires an interview.info_needed webhook listing the missing fields and suggested questions to guide the recruiter.
| Severity | Condition | Impact |
|---|---|---|
| CRITICAL | No identity provided (candidateRef, name, or email) OR position missing | Blocks all processing |
| HIGH | No qualifications or skills provided, or level missing | Triggers INFO_NEEDED |
| MEDIUM | Fewer than 3 qualifications/skills, or short job description | Warning only — does not block processing |
candidateRef as the identity field instead of candidateName and candidateEmail to avoid sending PII. Any one of the three satisfies the CRITICAL identity check.# Supply missing fields
curl -X PATCH https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/info \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{
"qualifications": [
"5+ years production TypeScript experience",
"Strong distributed systems background",
"Experience with microservices at scale"
],
"level": "SENIOR"
}'{
"message": "Interview information updated. Skill validation starting.",
"state": "VALIDATING_SKILLS"
}Stage 2: Plan Approval
When the AI generates an interview plan, the workflow enters PENDING state and fires an interview.plan_generated webhook. The recruiter reviews the plan and approves, rejects, or requests revisions. This stage is skipped when autoApprovePlans is enabled.
# Approve the plan
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/plan/approve \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{ "actorId": "li_recruiter_8821" }'{
"message": "Interview plan approved. Candidate interview link generated.",
"workflowState": "APPROVED",
"interviewLink": "{YOUR_APP_URL}/interview/join/eyJhbGc...",
"inmailDraft": {
"subject": "Senior Software Engineer Opportunity at Acme Corp — Interview Invitation",
"body": "Hi there,\n\nWe would love to invite you to complete an AI-powered interview for our Senior Software Engineer role at Acme Corp.\n\nPlease click the link below to begin:\n{YOUR_APP_URL}/interview/join/eyJhbGc...\n\nBest regards,\nThe Acme Corp Recruiting Team"
}
}The inmailDraft is generated by the Planner AI using the company name, position, and key qualifications. Send it to the candidate via LinkedIn InMail — the interview link is already substituted in the body.
# Reject the plan with feedback
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/plan/reject \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{
"reason": "The plan does not reflect the seniority level required. Please include more system design and architecture questions.",
"actorId": "li_recruiter_8821"
}'# Request targeted revisions without a full rejection
curl -X PATCH https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/plan/revise \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{
"comments": "Please add more system design questions. The candidate has 8 years of experience — reduce basic syntax checks.",
"actorId": "li_recruiter_8821"
}'Stage 3: Assessment Review
After the interview concludes, the AI generates a structured assessment. The workflow enters ASSESSMENT_PENDING state and fires an interview.assessment_pending webhook with the full report. The recruiter approves or rejects.
# Approve the assessment with optional score annotations
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/assessment/approve \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{
"actorId": "li_recruiter_8821",
"biasAnnotations": "Candidate was direct and confident. No bias concerns."
}'# Reject the assessment
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/assessment/reject \
-H "X-API-Key: your_api_key" \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json" \
-d '{
"reason": "Assessment scores do not match the observed interview performance.",
"actorId": "li_recruiter_8821"
}'HITL Endpoints Summary
| Stage | Method | Endpoint | Notes |
|---|---|---|---|
| Data Completion | PATCH | /integration/interviews/:runId/info | Supply missing fields by runId |
| Plan — Approve | POST | /integration/interviews/:runId/plan/approve | Returns interviewLink + inmailDraft |
| Plan — Reject | POST | /integration/interviews/:runId/plan/reject | Requires reason (min 5 chars) |
| Plan — Revise | PATCH | /integration/interviews/:runId/plan/revise | Targeted feedback without full rejection |
| Assessment — Approve | POST | /integration/interviews/:runId/assessment/approve | Optional score annotations |
| Assessment — Reject | POST | /integration/interviews/:runId/assessment/reject | Requires reason (min 5 chars) |
/admin/approvals provides a UI for all HITL operations. Recruiters can review plans, approve or reject, and provide feedback without making direct API calls.