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

text
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  CANCELLED

Auto-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.

SettingEffect
autoApprovePlans: false (default)Interview enters PENDING state — recruiter must approve before candidate link is issued
autoApprovePlans: truePlan 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.

SeverityConditionImpact
CRITICALNo identity provided (candidateRef, name, or email) OR position missingBlocks all processing
HIGHNo qualifications or skills provided, or level missingTriggers INFO_NEEDED
MEDIUMFewer than 3 qualifications/skills, or short job descriptionWarning only — does not block processing
Use candidateRef as the identity field instead of candidateName and candidateEmail to avoid sending PII. Any one of the three satisfies the CRITICAL identity check.
bash
# 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"
  }'
Response 200 — transitions to VALIDATING_SKILLS
{
  "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.

bash
# 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" }'
Response 200
{
  "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.

bash
# 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"
  }'
bash
# 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.

bash
# 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."
  }'
bash
# 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

StageMethodEndpointNotes
Data CompletionPATCH/integration/interviews/:runId/infoSupply missing fields by runId
Plan — ApprovePOST/integration/interviews/:runId/plan/approveReturns interviewLink + inmailDraft
Plan — RejectPOST/integration/interviews/:runId/plan/rejectRequires reason (min 5 chars)
Plan — RevisePATCH/integration/interviews/:runId/plan/reviseTargeted feedback without full rejection
Assessment — ApprovePOST/integration/interviews/:runId/assessment/approveOptional score annotations
Assessment — RejectPOST/integration/interviews/:runId/assessment/rejectRequires reason (min 5 chars)
The admin dashboard at /admin/approvals provides a UI for all HITL operations. Recruiters can review plans, approve or reject, and provide feedback without making direct API calls.
Was this page helpful?