Integration API

REST Endpoints

Complete endpoint reference for the Integration API.

All endpoints are under the /api/v1/integration base path. Every request must include either an X-API-Key header (recommended for server-to-server) or an Authorization: Bearer <jwt> header.

Endpoint Summary

MethodEndpointRequired StateDescription
POST/integration/interviewsAnySubmit an interview request
GET/integration/interviews/:runIdAnyGet status, plan, and assessment
DELETE/integration/interviews/:runIdActive (not terminal)Cancel an interview
PATCH/integration/interviews/:runId/infoINFO_NEEDEDSupply missing interview data
POST/integration/interviews/:runId/plan/approvePENDINGApprove the AI-generated plan
POST/integration/interviews/:runId/plan/rejectPENDINGReject the plan with feedback
PATCH/integration/interviews/:runId/plan/revisePENDINGRequest targeted plan revisions
POST/integration/interviews/:runId/assessment/approveASSESSMENT_PENDINGApprove the AI assessment
POST/integration/interviews/:runId/assessment/rejectASSESSMENT_PENDINGReject the assessment
POST/integration/interviews/:runId/assessment/chatASSESSMENT_PENDING or laterChat with AI about an assessment
DELETE/integration/interviews/:runId/candidate-dataAnyPurge candidate PII — preserves assessment
GET/integration/rankingsAnyCandidate rankings by score

POST /integration/interviews

Submit a new interview request. Returns a runId immediately. Use the runId for all subsequent calls.

Idempotency: Pass an externalId (your ATS application or job ID) to prevent duplicate interviews on retries. If an interview with the same externalId already exists for your account, the existing interview is returned.

Request Body

FieldTypeRequiredDescription
candidateRefstringPreferredOpaque partner-side candidate/application ID — preferred to avoid sending PII. Returned as-is in all webhooks for correlation.
candidateNamestringOptionalFull name — only needed if no candidateRef is provided
candidateEmailstringOptionalEmail — only required if OTP delivery to the candidate is needed
candidateProfilestringOptionalAnonymized profile context (e.g. "8 yrs backend, TypeScript expert") — do not include name or contact details
positionstringYesJob title being interviewed for
levelstringYesJUNIOR, MID, SENIOR, LEAD, or PRINCIPAL
qualificationsstring[]PreferredNatural-language recruiter qualification statements — parsed internally by Teamcast. Preferred over skills[].
skillsstring[]OptionalExplicit skill names — supported for backward compatibility. Used when qualifications[] is not provided.
jobDescriptionstringOptionalFull role description. Optional when qualifications[] has 2+ items.
companyNamestringOptionalCompany name — used in the Hiring Assistant's opening greeting and InMail draft
companyDescriptionstringOptionalBrief company overview — enriches greeting and InMail draft
externalIdstringOptionalYour ATS job or application ID — enables idempotent retries
candidateResumestringOptionalResume text — helps the planner generate targeted questions. Strip PII before sending.
Identity: Provide at least one of candidateRef, candidateName, or candidateEmail. candidateRef is the recommended option — it identifies the candidate without sending PII. Qualifications: Provide at least one of qualifications[] or skills[]. If any required field is missing, the interview enters INFO_NEEDED state and a webhook lists exactly what is needed.
Webhook URL is configured once per tenant in your account settings — not passed per-request. Contact your account manager to register or update your webhook endpoint and signing secret. Use autoApprovePlans: true in your tenant webhook config to skip the plan approval step entirely.

Example — Qualification-First (Recommended)

bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews \
  -H "X-API-Key: your_api_key" \
  -H "X-Tenant-ID: your_tenant_id" \
  -H "Content-Type: application/json" \
  -d '{
    "candidateRef": "li_app_a1b2c3d4",
    "candidateProfile": "8 years backend engineering, TypeScript and distributed systems background.",
    "position": "Senior Software Engineer",
    "level": "SENIOR",
    "qualifications": [
      "5+ years of production TypeScript experience",
      "Demonstrated ability to design distributed systems at scale",
      "Strong async/concurrency patterns knowledge"
    ],
    "companyName": "Acme Corp",
    "externalId": "li_job_app_8821"
  }'
Response 201 — data complete
{
  "runId": "run_1749123456_a1b2c3d4",
  "interviewId": "interview-uuid",
  "state": "VALIDATING_SKILLS",
  "message": "Interview request accepted. Skill validation in progress.",
  "dataQuality": "EXCELLENT"
}

Example — Incomplete Data

Response 201 — data incomplete
{
  "runId": "run_1749123456_a1b2c3d4",
  "interviewId": "interview-uuid",
  "state": "INFO_NEEDED",
  "message": "Missing critical data. Please provide the required fields.",
  "dataQuality": "POOR",
  "missingFields": [
    {
      "field": "qualifications",
      "severity": "HIGH",
      "reason": "No qualifications or skills provided",
      "question": "Please provide at least one qualification statement or skill"
    }
  ]
}

GET /integration/interviews/:runId

Returns the full current state of an interview, including the generated plan and assessment report when available. Recording URLs are signed and expire after 7 days.

bash
curl https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4 \
  -H "X-API-Key: your_api_key" \
  -H "X-Tenant-ID: your_tenant_id"
Response 200
{
  "runId": "run_1749123456_a1b2c3d4",
  "interviewId": "interview-uuid",
  "state": "PENDING",
  "plan": {
    "id": "plan-uuid",
    "generatedAt": "2024-01-15T10:45:00.000Z"
  }
}

DELETE /integration/interviews/:runId

Cancels an active interview. This is a soft delete — the record is retained for audit purposes with a CANCELLED state. Terminal states (COMPLETED, CANCELLED, ASSESSMENT_APPROVED) cannot be cancelled.

bash
curl -X DELETE https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4 \
  -H "X-API-Key: your_api_key" \
  -H "X-Tenant-ID: your_tenant_id" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Candidate withdrew from the process."
  }'
Response 200
{ "message": "Interview cancelled." }

PATCH /integration/interviews/:runId/info

Supplies missing interview fields when the interview is in INFO_NEEDED state. Only provide the fields listed in the interview.info_needed webhook — existing fields are preserved. After updating, the system re-validates and transitions to VALIDATING_SKILLS if all required fields are present.

bash
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 TypeScript experience",
      "Strong system design background"
    ],
    "level": "SENIOR"
  }'
Response 200 — all fields complete
{
  "message": "Interview information updated. Skill validation starting.",
  "state": "VALIDATING_SKILLS"
}
Response 200 — fields still missing
{
  "message": "Some required fields are still missing.",
  "state": "INFO_NEEDED",
  "missingFields": [
    {
      "field": "position",
      "severity": "CRITICAL",
      "reason": "Job position is required",
      "question": "Please specify the job position or title"
    }
  ]
}

POST /integration/interviews/:runId/plan/approve

Approves the AI-generated interview plan when the interview is in PENDING state. Returns the candidate-facing interview link and an AI-generated LinkedIn InMail draft pre-filled with the interview link.

bash
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"
  }
}

POST /integration/interviews/:runId/plan/reject

Rejects the AI-generated plan when the interview is in PENDING state. The AI agent uses your reason as feedback when regenerating the plan.

bash
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"
  }'
Response 200
{
  "message": "Plan rejected. The AI agent will regenerate it using your feedback.",
  "workflowState": "GENERATING_PLAN"
}

PATCH /integration/interviews/:runId/plan/revise

Requests targeted revisions to the plan without a full rejection. The AI agent incorporates your comments when regenerating.

bash
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"
  }'
Response 200
{
  "message": "Revision request accepted. The plan is being regenerated.",
  "workflowState": "GENERATING_PLAN"
}

POST /integration/interviews/:runId/assessment/approve

Approves the AI-generated assessment report when the interview is in ASSESSMENT_PENDING state. All body fields are optional.

Optional Annotation Fields

FieldTypeDescription
actorIdstringRecruiter ID for the audit trail
recruiterScoresobjectScore overrides keyed by dimension and sub-dimension
subDimensionAnnotationsobjectQualitative notes per sub-dimension
competencyWeightOverridesobjectCustom competency weights (must sum to 1.0)
evidenceConfirmationsstring[]Evidence statements the recruiter confirms
biasAnnotationsstringFree-text note for the bias audit trail
bash
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 noted."
  }'
Response 200
{
  "message": "Assessment approved. The full report has been sent via webhook.",
  "workflowState": "ASSESSMENT_APPROVED"
}

POST /integration/interviews/:runId/assessment/reject

Rejects the AI assessment report. The interview is marked CANCELLED and the report is suppressed.

bash
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"
  }'
Response 200
{
  "message": "Assessment rejected. Interview has been cancelled.",
  "workflowState": "CANCELLED"
}

POST /integration/interviews/:runId/assessment/chat

Ask free-form questions about a completed assessment. The AI answers grounded in the structured assessment data.

bash
curl -X POST https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/assessment/chat \
  -H "X-API-Key: your_api_key" \
  -H "X-Tenant-ID: your_tenant_id" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Why did the candidate score lower on system design compared to their overall score?",
    "history": []
  }'
Response 200
{
  "response": "The candidate scored 72 on system design versus an overall 85. During the distributed systems question, they outlined a correct microservices approach but did not address failure handling or data consistency trade-offs."
}

DELETE /integration/interviews/:runId/candidate-data

Permanently removes candidate PII from an interview record while preserving the assessment report and audit trail. Use this to honor data deletion requests or to enforce your retention policy.

The following fields are wiped: candidateName, candidateEmail, candidateRef, candidateProfile, candidateResume, and all OTP and session tokens. Assessment scores, scores, and the structured report are retained. An immutable audit log entry is created for every purge.

bash
curl -X DELETE https://mayaapi.teamcast.ai/api/v1/integration/interviews/run_1749123456_a1b2c3d4/candidate-data \
  -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": "Candidate PII purged successfully.",
  "purgedAt": "2024-03-01T14:30:00.000Z",
  "fieldsWiped": ["candidateName", "candidateEmail", "candidateRef", "candidateProfile", "candidateResume", "sessionTokens", "otpRecords"]
}
This operation is irreversible. The wiped fields cannot be recovered. The assessment report and scores are preserved as they contain no direct PII.

GET /integration/rankings

Returns all candidates with completed and approved assessments, ranked by overall score descending.

Query Parameters

ParameterTypeDescription
positionstringFilter by position (case-insensitive substring match)
levelstringFilter by level: JUNIOR, MID, SENIOR, LEAD, or PRINCIPAL
bash
curl "https://mayaapi.teamcast.ai/api/v1/integration/rankings?position=Senior+Engineer&level=SENIOR" \
  -H "X-API-Key: your_api_key" \
  -H "X-Tenant-ID: your_tenant_id"
Response 200
[
  {
    "rank": 1,
    "interviewId": "interview-uuid",
    "candidateRef": "li_app_a1b2c3d4",
    "candidateName": null,
    "position": "Senior Software Engineer",
    "level": "SENIOR",
    "overallScore": 87,
    "recommendation": "STRONG_HIRE",
    "finalVerdict": "ASSESSMENT_APPROVED",
    "verdictAt": "2024-01-15T15:30:00.000Z"
  }
]
candidateName and candidateEmail will be null when the interview was created using only a candidateRef. Use candidateRef to look up the candidate in your own system.
Webhook notifications are sent to the URL registered in your tenant account settings. See the Webhooks guide for the full event reference and HMAC verification.

API Tryout

Test the Integration API endpoints interactively. Your API key is kept in sessionStorage for this browser tab only and never sent to any third party.

TryoutIntegration API
Uses your Platform API Key

Credentials

Credentials saved to sessionStorage for this tab only. Never logged or sent to a third party.

Submit a new interview request. Returns a runId immediately.

Request Body

POSThttps://mayaapi.teamcast.ai/api/v1/integration/interviews
Was this page helpful?