Integration API
Data Validation
How the system evaluates incoming interview data and routes to INFO_NEEDED or VALIDATING_SKILLS.
When an interview creation request arrives, the DataValidationService evaluates each field against a three-tier severity model. The result determines whether processing proceeds immediately or enters the HITL INFO_NEEDED state for data completion.
Severity Tiers
| Severity | Impact | State Result |
|---|---|---|
| CRITICAL | Cannot proceed without this field | INFO_NEEDED |
| HIGH | Significantly degrades plan quality | INFO_NEEDED |
| MEDIUM | Minor quality reduction | Warning only — proceeds |
Field Rules
The validator uses flexible identity and qualification rules designed for LinkedIn integration — most fields are optional when better alternatives are provided.
| Field / Rule | Severity | Condition | Question Sent to HITL |
|---|---|---|---|
| Identity (trio) | CRITICAL | At least one of: candidateRef, candidateName, or candidateEmail must be present | Please provide a candidateRef, candidate name, or email to identify the candidate |
| position | CRITICAL | Required, non-empty | Please specify the job position or title |
| level | HIGH | Required: JUNIOR/MID/SENIOR/LEAD/PRINCIPAL | Please specify the seniority level |
| Qualifications (pair) | HIGH | At least one of: qualifications[] (1+ item) or skills[] (1+ item) must be present | Please provide qualification statements or skills for this role |
| jobDescription | HIGH | Required if qualifications[] has fewer than 2 items AND skills[] is empty | Please provide a job description or at least 2 qualification statements |
| jobDescription length | MEDIUM | Recommended 100+ chars | A longer description produces more tailored interview questions |
| Qualification depth | MEDIUM | Recommended 3+ qualifications or skills | Consider adding more qualifications for better plan quality |
qualifications[] has 2 or more items, jobDescription is not required — Teamcast derives context directly from the qualification statements. skills[] is also optional and supported for backward compatibility with existing integrations.Data Quality Scores
| Score | Criteria |
|---|---|
| EXCELLENT | No CRITICAL/HIGH issues, job description 100+ chars or 3+ qualifications |
| ACCEPTABLE | No CRITICAL/HIGH issues but has MEDIUM warnings |
| POOR | Has HIGH severity issues — triggers INFO_NEEDED |
| INSUFFICIENT | Has CRITICAL missing fields — triggers INFO_NEEDED |
Validation Logic
// Simplified DataValidationService logic
validateInterviewData(dto: CreateInterviewRequestDto): ValidationResult {
const issues: ValidationIssue[] = [];
// CRITICAL: identity — at least one of candidateRef, name, or email
const hasIdentity = dto.candidateRef || dto.candidateName || dto.candidateEmail;
if (!hasIdentity) {
issues.push({ field: 'candidateRef', severity: 'CRITICAL', ... });
}
// CRITICAL: position
if (!dto.position?.trim()) {
issues.push({ field: 'position', severity: 'CRITICAL', ... });
}
// HIGH: level
if (!dto.level) {
issues.push({ field: 'level', severity: 'HIGH', ... });
}
// HIGH: qualifications OR skills
const hasQualifications = dto.qualifications?.length > 0;
const hasSkills = dto.skills?.length > 0;
if (!hasQualifications && !hasSkills) {
issues.push({ field: 'qualifications', severity: 'HIGH', ... });
}
// HIGH: jobDescription — only required when qualifications < 2
const qualCount = dto.qualifications?.length ?? 0;
if (qualCount < 2 && !hasSkills) {
if (!dto.jobDescription || dto.jobDescription.length < 50) {
issues.push({ field: 'jobDescription', severity: 'HIGH', ... });
}
}
const needsHITL = issues.some(
(i) => i.severity === 'CRITICAL' || i.severity === 'HIGH'
);
return {
canProceed: !needsHITL,
needsHITL,
missingFields: issues,
dataQuality: computeQuality(issues),
};
}INFO_NEEDED Response
When validation fails, the create endpoint returns a structured 201 (not an error) with the interview ID and the list of issues:
{
"runId": "agno-run-uuid",
"interviewId": "interview-uuid",
"state": "INFO_NEEDED",
"dataQuality": "POOR",
"missingFields": [
{
"field": "qualifications",
"severity": "HIGH",
"reason": "No qualifications or skills provided",
"question": "Please provide at least one qualification statement or skill"
},
{
"field": "level",
"severity": "HIGH",
"reason": "Seniority level not specified",
"question": "Please specify the seniority level (JUNIOR/MID/SENIOR/LEAD/PRINCIPAL)"
}
]
}Completing Missing Info
After receiving an INFO_NEEDED state, use PATCH /integration/interviews/:runId/info to supply the missing fields. The system re-validates — if all issues are resolved, it transitions to VALIDATING_SKILLS.
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 and distributed systems background"
],
"level": "SENIOR"
}'{
"message": "Interview information completed. Skill validation starting.",
"state": "VALIDATING_SKILLS"
}qualifications[] with 2+ items in the initial request to skip jobDescription and achieve EXCELLENT data quality without the INFO_NEEDED state.