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

SeverityImpactState Result
CRITICALCannot proceed without this fieldINFO_NEEDED
HIGHSignificantly degrades plan qualityINFO_NEEDED
MEDIUMMinor quality reductionWarning 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 / RuleSeverityConditionQuestion Sent to HITL
Identity (trio)CRITICALAt least one of: candidateRef, candidateName, or candidateEmail must be presentPlease provide a candidateRef, candidate name, or email to identify the candidate
positionCRITICALRequired, non-emptyPlease specify the job position or title
levelHIGHRequired: JUNIOR/MID/SENIOR/LEAD/PRINCIPALPlease specify the seniority level
Qualifications (pair)HIGHAt least one of: qualifications[] (1+ item) or skills[] (1+ item) must be presentPlease provide qualification statements or skills for this role
jobDescriptionHIGHRequired if qualifications[] has fewer than 2 items AND skills[] is emptyPlease provide a job description or at least 2 qualification statements
jobDescription lengthMEDIUMRecommended 100+ charsA longer description produces more tailored interview questions
Qualification depthMEDIUMRecommended 3+ qualifications or skillsConsider adding more qualifications for better plan quality
Qualification-first: When 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

ScoreCriteria
EXCELLENTNo CRITICAL/HIGH issues, job description 100+ chars or 3+ qualifications
ACCEPTABLENo CRITICAL/HIGH issues but has MEDIUM warnings
POORHas HIGH severity issues — triggers INFO_NEEDED
INSUFFICIENTHas CRITICAL missing fields — triggers INFO_NEEDED

Validation Logic

typescript
// 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:

json
{
  "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.

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 and distributed systems background"
    ],
    "level": "SENIOR"
  }'
Response 200
{
  "message": "Interview information completed. Skill validation starting.",
  "state": "VALIDATING_SKILLS"
}
Use qualifications[] with 2+ items in the initial request to skip jobDescription and achieve EXCELLENT data quality without the INFO_NEEDED state.
Was this page helpful?