{"openapi":"3.1.0","info":{"title":"tview Partner API","version":"1.3.1","description":"Server-to-server API for integrating tview recruitment flows with partner platforms and job boards.\n\n## Data model\n\n- **Project** — the top-level recruitment container. Create one project per role or hiring round, not per candidate or per screening.\n- **Pipeline steps** — ordered stages within a project. Persisted API step `type` values are now `screening`, `coding_task`, `video_interview`, `case_study`, `documents_upload`, or `custom`.\n- **Application** — a candidate's journey through one project.\n- **Step result** — per-application, per-step state: answers, code submissions, evaluations, and recordings.\n- **Interview training session** — candidate practice interview generated from a project, job offer, or raw posting. It is not part of the evaluated recruitment pipeline unless a partner maps it into their own flow.\n\n## Recommended integration pattern\n\n1. Create a project for each distinct role or hiring round.\n2. Configure its pipeline with one or more steps.\n3. Invite candidates into the project. Each candidate gets one application per project.\n4. Let candidates complete pipeline steps; results and evaluations appear on step results.\n\nAvoid creating a new project for every individual screening — screenings are pipeline steps, not standalone entities.\n\n## Pipeline step types\n\n- `screening` — questionnaire/screening step. Questions live in `config.questions` or can be composed per application via `/api/v1/applications/{id}/screening-compose`.\n- `coding_task` — coding or technical task. Main task body is usually in `config.challenge`; optional fields include `config.language`, `config.difficulty`, and `config.instructions`.\n- `video_interview` — video interview step. Questions live in `config.questions`; `config.recordingEnabled=false` disables session recording.\n- `case_study` — case study step. Use `config.brief` and optional `config.format` (`written`, `presentation`, or `both`).\n- `documents_upload` — document upload step. Use `config.requiredDocuments`, `config.maxFileSizeMb`, `config.allowMultiple`, and `config.acceptedFormats`.\n- `custom` — extension point for non-standard steps. Use `config.customType` for machine-readable custom behavior.\n\nBackward compatibility: payloads using the old representation `type: custom` with `config.subType: case_study` or `config.subType: documents_upload` are still accepted and normalized to the new first-class types.\n\n## Authentication\n\nBearer API keys (`tv_live_*` / `tv_test_*`). Authenticated responses include `X-Request-Id`, `X-Correlation-Id`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`.\n\n## Idempotency\n\nPOST `/api/v1/projects`, `/api/v1/projects/{id}/generate-pipeline`, `/api/v1/projects/{id}/candidates`, `/api/v1/projects/{id}/candidates/bulk`, `/api/v1/applications/{id}/evaluate`, `/api/v1/interview-training/sessions`, `/api/v1/interview-training/sessions/{id}/answers`, `/api/v1/interview-training/sessions/{id}/summary`, and `/api/v1/webhooks/test` support the `Idempotency-Key` header.\n\n## Partner-hosted apply flow\n\n- create tokenized apply sessions without candidate signup/login\n- mark candidate profiles as partner-provided and skip hosted profile collection\n- store partner-provided consent\n- customize hosted application screen copy per application with `applicationPage`\n- optionally switch the hosted flow into vanilla shadcn whitelabel mode with per-application `hostedBranding`\n- echo `externalCandidateId` and public `metadata` in application APIs and webhooks\n\n## Screening composition\n\n`POST /api/v1/applications/{id}/screening-compose` composes manual and generated questions per application. Use `stepId` when an application has more than one screening step. Screening submissions persist a question snapshot so later edits do not rewrite history.\n\n## Interview training\n\n- create practice sessions from a project, job offer, or raw job posting text\n- serve the next unanswered question for embedded candidate flows\n- submit candidate practice answers and return coaching feedback\n- generate a final readiness report for the specific posting\n\n## Metered endpoints\n\n- `POST /api/v1/projects/{id}/generate-pipeline` → generation credit\n- `POST /api/v1/applications/{id}/evaluate` → screening/code evaluation credit\n- `POST /api/v1/interview-training/sessions` → generation credit when AI generation succeeds\n- `POST /api/v1/interview-training/sessions/{id}/answers` → screening evaluation credit when AI feedback succeeds\n- `POST /api/v1/interview-training/sessions/{id}/summary` → summary credit when AI summary succeeds\n\n## Webhooks\n\nPayload contract: `{ event, timestamp, data }` with HMAC SHA-256 signature in `X-Tview-Signature`.\n\nAvailable application and usage events: `application.created`, `application.started`, `application.completed`, `application.decided`, `application.stage_changed`, `screening.submitted`, `screening.evaluated`, `code.submitted`, `code.evaluated`, `interview.started`, `interview.completed`, `balance.low`, `balance.depleted`.\n\n`application.decided` is sent when a recruiter moves a candidate forward, rejects them, records a withdrawal or reopens the application. `data.decision` carries `type` (`advanced`, `rejected`, `withdrawn`, `reopened`), the resulting `status`, `reason` and `decidedAt`. Internal recruiter notes are never included.\n\n`application.stage_changed` is sent when a candidate moves between hiring stages (for example from AI screening to Interview). `data.stage` carries `from` and `to`, each with `id`, `kind` (`new`, `screening`, `interview`, `offer`, `hired`) and `name`.\n\n## Metadata\n\n`metadata.__tview` is reserved for internal use and must not be sent by partners."},"servers":[{"url":"https://tview.work","description":"Production API (primary)"},{"url":"https://jobs.tview.work","description":"Production API (candidate host)"},{"url":"http://localhost:3000","description":"Local development"}],"externalDocs":{"description":"Companion docs and onboarding notes","url":"https://tview.work/docs"},"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Partner API key in the format `tv_live_*` or `tv_test_*`"}},"parameters":{"PageParam":{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1}},"LimitParam":{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},"ProjectId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"ApplicationId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"CandidateId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"InterviewTrainingSessionId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":1,"maxLength":255}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}},"PaginationMeta":{"type":"object","properties":{"total":{"type":"integer","example":42},"page":{"type":"integer","example":1},"limit":{"type":"integer","example":20}}},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"roleType":{"type":"string","nullable":true},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectReadiness":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"hasScreeningStep":{"type":"boolean"},"hasDefaultHostedBranding":{"type":"boolean"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"isWhitelabelActive":{"type":"boolean"},"effectiveHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"hasActiveJobOffer":{"type":"boolean"},"issues":{"type":"array","items":{"type":"string"}}}},"PipelineStep":{"type":"object","description":"Persisted recruitment pipeline step. `case_study` and `documents_upload` are first-class step types. Legacy `type: custom` plus `config.subType` payloads for these steps are still accepted and normalized.","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"title":{"type":"string"},"order":{"type":"integer"},"config":{"type":"object","additionalProperties":true,"description":"Step-specific configuration. For video_interview, recordingEnabled defaults to true; set recordingEnabled=false to disable session recording. For case studies use type=case_study with config.brief and optional config.format. For document uploads use type=documents_upload with config.requiredDocuments, config.maxFileSizeMb, config.allowMultiple, and config.acceptedFormats.","properties":{"recordingEnabled":{"type":"boolean","default":true},"subType":{"type":"string","enum":["case_study","documents_upload"],"deprecated":true,"description":"Legacy compatibility only. Prefer first-class step type values."},"customType":{"type":"string","example":"manual_review"},"brief":{"type":"string","description":"Case study brief for type=case_study"},"format":{"type":"string","enum":["written","presentation","both"]},"requiredDocuments":{"type":"array","items":{"type":"string"},"description":"Required document names for type=documents_upload"},"maxFileSizeMb":{"type":"integer"},"allowMultiple":{"type":"boolean"},"acceptedFormats":{"type":"string","example":".pdf,.doc,.docx,.txt,.zip"},"questions":{"type":"array","items":{},"description":"Screening or interview questions"},"challenge":{"type":"string","description":"Coding task challenge body"},"instructions":{"type":"string"},"durationMinutes":{"type":"integer"}}},"isRequired":{"type":"boolean"}}},"GeneratedPipelineStep":{"type":"object","description":"AI-generated pipeline node. `type` is the persisted API/database type. `nodeType` mirrors the generated semantic node and is retained for clients that distinguish generated vs persisted shapes.","properties":{"type":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"nodeType":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"title":{"type":"string"},"description":{"type":"string"},"isRequired":{"type":"boolean"},"config":{"type":"object","additionalProperties":true}}},"CandidateInvite":{"type":"object","required":["email","firstName","lastName"],"properties":{"email":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phone":{"type":"string"},"cvText":{"type":"string"},"cvUrl":{"type":"string","format":"uri"},"externalCandidateId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"profileCollectionMode":{"type":"string","enum":["hosted","partner_provided"]},"partnerProvidedConsent":{"type":"object","additionalProperties":true,"properties":{"dataProcessing":{"type":"boolean"},"aiProcessing":{"type":"boolean"},"recording":{"type":"boolean"},"profileSharing":{"type":"boolean"},"source":{"type":"string"},"collectedAt":{"type":"string","format":"date-time"},"metadata":{"type":"object","additionalProperties":true}}},"profile":{"$ref":"#/components/schemas/CandidateProfileUpsert"},"applicationPage":{"$ref":"#/components/schemas/ApplicationPageInput"},"hostedBranding":{"$ref":"#/components/schemas/HostedBrandingInput"}}},"ApplicationPageInput":{"type":"object","description":"Per-application hosted application screen copy overrides. Supports raw copy or templates with variables.","properties":{"locale":{"type":"string","enum":["en","pl"]},"title":{"type":"string"},"subtitle":{"type":"string"},"description":{"type":"string"},"profileNotice":{"type":"string"},"consentNotice":{"type":"string"},"ctaLabel":{"type":"string"},"titleTemplate":{"type":"string"},"subtitleTemplate":{"type":"string"},"descriptionTemplate":{"type":"string"},"profileNoticeTemplate":{"type":"string"},"consentNoticeTemplate":{"type":"string"},"variables":{"type":"object","additionalProperties":true},"labels":{"type":"object","properties":{"applicationHeader":{"type":"string"},"processHeader":{"type":"string"},"profileSectionTitle":{"type":"string"},"consentSectionTitle":{"type":"string"}}}}},"ApplicationPageResolved":{"type":"object","description":"Resolved hosted application screen copy returned by application APIs after templates/defaults are applied.","properties":{"locale":{"type":"string","enum":["en","pl"]},"title":{"type":"string"},"subtitle":{"type":"string"},"description":{"type":"string"},"profileNotice":{"type":"string"},"consentNotice":{"type":"string"},"ctaLabel":{"type":"string"},"labels":{"type":"object","properties":{"applicationHeader":{"type":"string"},"processHeader":{"type":"string"},"profileSectionTitle":{"type":"string"},"consentSectionTitle":{"type":"string"}}}}},"HostedBrandingInput":{"type":"object","description":"Per-application hosted branding overrides. Use `mode=whitelabel` to render the hosted flow with a neutral shadcn-style shell and optional partner logo/colors.","properties":{"mode":{"type":"string","enum":["default","whitelabel"]},"logoUrl":{"type":"string","format":"uri"},"companyName":{"type":"string"},"primaryColor":{"type":"string","pattern":"^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"},"accentColor":{"type":"string","pattern":"^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"}}},"HostedBrandingResolved":{"type":"object","description":"Resolved hosted branding returned by application APIs after defaults/fallbacks are applied.","properties":{"mode":{"type":"string","enum":["default","whitelabel"]},"logoUrl":{"type":"string","format":"uri","nullable":true},"companyName":{"type":"string","nullable":true},"primaryColor":{"type":"string","nullable":true},"accentColor":{"type":"string","nullable":true},"isWhitelabel":{"type":"boolean"}}},"ScreeningQuestionEntry":{"type":"object","description":"Question-level screening result entry used in application APIs and screening webhooks.","properties":{"questionId":{"type":"string"},"source":{"type":"string","enum":["manual","generated"]},"externalQuestionId":{"type":"string","nullable":true},"text":{"type":"string"},"answer":{"nullable":true},"score":{"type":"number","nullable":true},"metadata":{"type":"object","additionalProperties":true,"nullable":true}}},"ScreeningComposeRequest":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"locale":{"type":"string","enum":["en","pl"]},"manualQuestions":{"type":"array","items":{"type":"object","properties":{"externalQuestionId":{"type":"string"},"text":{"type":"string"},"type":{"type":"string","enum":["scale","single_choice","multiple_choice","ordering","open"]},"options":{"type":"array","items":{"type":"string"}},"scaleMin":{"type":"integer"},"scaleMax":{"type":"integer"},"scaleMinLabel":{"type":"string"},"scaleMaxLabel":{"type":"string"},"isRequired":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":true}}}},"generatedQuestions":{"type":"object","properties":{"enabled":{"type":"boolean"},"count":{"type":"integer"},"basedOn":{"type":"array","items":{"type":"string"}},"instructions":{"type":"string"}}},"mergeStrategy":{"type":"string","enum":["manual_first","generated_first","interleave"]},"deduplicate":{"type":"boolean"},"replaceExisting":{"type":"boolean"}}},"CandidateProfileUpsert":{"type":"object","properties":{"headline":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"skills":{"type":"array","items":{"type":"string"}},"experienceYears":{"type":"integer","nullable":true},"cvUrl":{"type":"string","format":"uri","nullable":true},"linkedinUrl":{"type":"string","format":"uri","nullable":true},"githubUrl":{"type":"string","format":"uri","nullable":true}}},"InterviewTrainingSessionCreate":{"type":"object","description":"Provide exactly one of projectId, jobOfferId, or postingText.","properties":{"projectId":{"type":"string","format":"uuid"},"jobOfferId":{"type":"string","format":"uuid"},"postingText":{"type":"string","minLength":100,"maxLength":50000},"title":{"type":"string","maxLength":500},"roleType":{"type":"string","maxLength":100},"locale":{"type":"string","enum":["en","pl"],"default":"en"},"questionCount":{"type":"integer","minimum":3,"maximum":12,"default":6}}},"InterviewTrainingQuestion":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["hr","technical","experience","situational"]},"text":{"type":"string"},"expectedSignals":{"type":"array","items":{"type":"string"}}}},"InterviewTrainingFeedback":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"summary":{"type":"string"},"strengths":{"type":"array","items":{"type":"string"}},"improvements":{"type":"array","items":{"type":"string"}},"suggestedAnswer":{"type":"string"}}},"InterviewTrainingAnswerCreate":{"type":"object","required":["questionId","answerText"],"properties":{"questionId":{"type":"string"},"answerText":{"type":"string","maxLength":20000}}},"InterviewTrainingAnswer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sessionId":{"type":"string","format":"uuid"},"questionId":{"type":"string"},"questionIndex":{"type":"integer"},"questionText":{"type":"string"},"answerText":{"type":"string"},"feedback":{"$ref":"#/components/schemas/InterviewTrainingFeedback"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"InterviewTrainingSummary":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"readiness":{"type":"string","enum":["low","medium","high"]},"summary":{"type":"string"},"strengths":{"type":"array","items":{"type":"string"}},"gaps":{"type":"array","items":{"type":"string"}},"nextSteps":{"type":"array","items":{"type":"string"}}}},"InterviewTrainingProgress":{"type":"object","properties":{"answered":{"type":"integer"},"total":{"type":"integer"},"completed":{"type":"boolean"}}},"InterviewTrainingSession":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid","nullable":true},"jobOfferId":{"type":"string","format":"uuid","nullable":true},"sourceType":{"type":"string","enum":["project","job_offer","raw_text"]},"status":{"type":"string","enum":["active","completed"]},"title":{"type":"string"},"roleType":{"type":"string","nullable":true},"locale":{"type":"string","enum":["en","pl"]},"questions":{"type":"array","items":{"$ref":"#/components/schemas/InterviewTrainingQuestion"}},"summary":{"anyOf":[{"$ref":"#/components/schemas/InterviewTrainingSummary"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"ShortlistCandidate":{"type":"object","required":["applicationId","overall","overallLower","overallUpper","coverage","gateStatus","conflicts"],"properties":{"applicationId":{"type":"string","format":"uuid"},"overall":{"type":"number","example":71.25},"overallLower":{"type":"number","example":66.5},"overallUpper":{"type":"number","example":76},"coverage":{"type":"number","minimum":0,"maximum":1,"description":"Share of rubric competencies carrying evidence"},"gateStatus":{"type":"string","enum":["pass","failed","insufficient_evidence"]},"conflicts":{"type":"array","items":{"type":"string"},"description":"Competency keys with contradictory evidence"},"rank":{"type":"integer","minimum":1,"description":"1-based position among ranked candidates. Absent on pinned candidates, which lead the list."}}},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"secret":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"HealthChecks":{"type":"object","properties":{"database":{"type":"boolean"},"blob":{"type":"boolean"},"ai":{"type":"boolean"},"tavus":{"type":"boolean"},"stripe":{"type":"boolean"},"workos":{"type":"boolean"}}}},"responses":{"Unauthorized":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"ValidationError":{"description":"Request validation failed","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"Forbidden":{"description":"Partner account is suspended","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"RateLimited":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}}}},"paths":{"/api/v1/health":{"get":{"summary":"Health status","tags":["Health"],"security":[],"responses":{"200":{"description":"Health check result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"$ref":"#/components/schemas/HealthChecks"}}}}}},"503":{"description":"Service degraded","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"$ref":"#/components/schemas/HealthChecks"}}}}}}}}},"/api/v1/ready":{"get":{"summary":"Readiness status","tags":["Health"],"security":[],"responses":{"200":{"description":"Service is ready","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ready"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object","properties":{"database":{"type":"boolean"},"env":{"type":"boolean"}}}}}}}},"503":{"description":"Service is not ready","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"not_ready"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object","properties":{"database":{"type":"boolean"},"env":{"type":"boolean"}}}}}}}}}}},"/api/v1/projects":{"get":{"summary":"List projects","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","active","archived","closed"]}}],"responses":{"200":{"description":"Project list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"summary":"Create project","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"roleType":{"type":"string"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingInput"},"pipeline":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"responses":{"201":{"description":"Project created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/projects/{id}":{"get":{"summary":"Get project","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Project details","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/Project"},{"type":"object","properties":{"pipeline":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}},"candidateCount":{"type":"integer"}}}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Update project","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string","nullable":true},"roleType":{"type":"string","nullable":true},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"defaultHostedBranding":{"anyOf":[{"$ref":"#/components/schemas/HostedBrandingInput"},{"type":"null"}]}}}}}},"responses":{"200":{"description":"Updated project","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Archive project","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Project archived","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"archived"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/readiness":{"get":{"summary":"Get project readiness","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Project readiness summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ProjectReadiness"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/pipeline":{"get":{"summary":"List pipeline steps","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Pipeline steps","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Replace pipeline","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["steps"],"properties":{"steps":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"responses":{"200":{"description":"Updated pipeline","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"A removed pipeline step is still referenced by an application","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/projects/{id}/generate-pipeline":{"post":{"summary":"Generate AI pipeline","description":"Generates a pipeline proposal. Returned steps include persisted `type` plus `nodeType`; `case_study` and `documents_upload` are first-class step types.","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"roleType":{"type":"string"}}}}}},"responses":{"200":{"description":"Generated pipeline proposal","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"steps":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedPipelineStep"}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/projects/{id}/context":{"get":{"summary":"List project context documents","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Context records","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Upload project context","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","name"],"properties":{"type":{"type":"string","enum":["job_spec","rubric","requirements","other"]},"name":{"type":"string"},"content":{"type":"string"},"fileUrl":{"type":"string","format":"uri"}}}},"multipart/form-data":{"schema":{"type":"object","required":["type","name"],"properties":{"type":{"type":"string","enum":["job_spec","rubric","requirements","other"]},"name":{"type":"string"},"content":{"type":"string"},"fileUrl":{"type":"string","format":"uri"},"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Context stored","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/apply-url":{"get":{"summary":"Get public project apply permalink","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Public candidate-facing permalink on the jobs host","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"kind":{"type":"string","enum":["offer_permalink","marketplace_fallback"]}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/candidates":{"get":{"summary":"List project candidates","description":"Lists candidate/application pairs for a project. Each row includes public `metadata` plus any resolved per-application `applicationPage` and `hostedBranding` overrides.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","schema":{"type":"string","enum":["new","invited","in_progress","completed","rejected","accepted","withdrawn"]}}],"responses":{"200":{"description":"Candidate list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Create tokenized candidate application session","description":"Creates or reuses a candidate/application pair and returns a hosted `applyUrl`. Supports partner-provided profile data, consent, metadata, per-application hosted screen copy overrides via `applicationPage`, and hosted whitelabel theming via `hostedBranding`.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateInvite"}}}},"responses":{"200":{"description":"Candidate invited","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"candidateId":{"type":"string","format":"uuid"},"applicationId":{"type":"string","format":"uuid"},"token":{"type":"string"},"applyUrl":{"type":"string","format":"uri"},"externalCandidateId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"profileCollectionMode":{"type":"string","enum":["hosted","partner_provided"]},"partnerProvidedConsent":{"type":"object","additionalProperties":true},"applicationPage":{"$ref":"#/components/schemas/ApplicationPageResolved"},"hostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/projects/{id}/candidates/bulk":{"post":{"summary":"Bulk invite candidates","description":"Creates or reuses candidate/application pairs in bulk. Each successful result includes the tokenized `applyUrl`, public `metadata`, and resolved `applicationPage` / `hostedBranding` for that application.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["candidates"],"properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/CandidateInvite"}}}}}}},"responses":{"200":{"description":"Bulk import result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/projects/{id}/shortlist":{"get":{"summary":"Get project shortlist","description":"Returns the deterministic shortlist for a project: pinned candidates first, then ranked candidates numbered from 1. Candidates blocked by a failed gate or by thin evidence are not returned. Scores are on a 0-100 scale; `overallLower` / `overallUpper` bound the score interval and are not clamped to that range. Responses carry no candidate identity — join on `applicationId`.","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"mode","in":"query","description":"Ranking signal. `lcb` (default) sorts on the lower confidence bound, so a confident score outranks a speculative one; `mean` sorts on the point estimate.","schema":{"type":"string","enum":["lcb","mean"],"default":"lcb"}}],"responses":{"200":{"description":"Project shortlist","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","required":["mode","generatedAt","candidates"],"properties":{"mode":{"type":"string","enum":["lcb","mean"]},"generatedAt":{"type":"string","format":"date-time"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/ShortlistCandidate"}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/applications/{id}":{"get":{"summary":"Get application details","description":"Returns application status, hosted application page copy, hosted whitelabel branding, step-level results, and screening `questionEntries` that preserve question origin (`manual` vs `generated`). Completed applications also expose `recording`, `recordingUrl`, and `transcript` when a video interview recording/transcript is available. Recording URLs are signed, expire after one hour, and are browser-openable without Partner API headers.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Application details","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/screening-compose":{"post":{"summary":"Compose step-aware screening questions for an application","description":"Composes a screening question set from partner-provided manual questions and optional tview-generated profile-aware questions. If an application has multiple screening steps, pass `stepId` to target the correct step. Submitted screening snapshots are immutable and preserved in later reads/webhooks.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningComposeRequest"}}}},"responses":{"200":{"description":"Composed question set","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"questionSetId":{"type":"string"},"generationVersion":{"type":"integer"},"questions":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/applications/{id}/recording":{"get":{"summary":"Get signed interview recording URL","description":"Returns a browser-openable signed URL for completed application recordings. The signed URL expires after one hour and does not require Partner API headers when opened in a browser.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Recording URL","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"source":{"type":"string","enum":["tavus","browser"]},"contentType":{"type":"string","enum":["video/mp4","video/webm"]},"expiresAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/recording/browser":{"get":{"summary":"Stream a completed browser recording","description":"Streams the latest completed video-interview recording from private storage. This endpoint requires a Partner API bearer key and application ownership; despite its name it is not an unauthenticated browser URL. Proxy it through your server, or obtain a short-lived signed URL from the recording endpoint for direct browser playback. Returns video/webm (or the recorded MIME type) with Cache-Control: private, no-store. If a finalized recording is unavailable, stored chunks are streamed in order.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Private recording stream","content":{"video/webm":{"schema":{"type":"string","format":"binary"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/recording/signed":{"get":{"summary":"Open signed interview recording","description":"Public, short-lived signed recording URL target. Partners should obtain this URL from `GET /api/v1/applications/{id}` or `GET /api/v1/applications/{id}/recording`; do not construct it manually.","tags":["Applications"],"security":[],"parameters":[{"$ref":"#/components/parameters/ApplicationId"},{"name":"expires","in":"query","required":true,"schema":{"type":"integer"}},{"name":"signature","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Browser recording stream","content":{"video/webm":{"schema":{"type":"string","format":"binary"}}}},"302":{"description":"Redirect to hosted recording"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/evaluate":{"post":{"summary":"Evaluate application step","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stepId"],"properties":{"stepId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Evaluation result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"score":{"type":"number"},"evaluation":{"type":"object","description":"Always carries summary, strengths, weaknesses and recommendation, plus correctness and codeQuality for coding steps. A project scored against a rubric additionally returns mode=\"two_stage\" with rubric, competencies and criterionScores; single-shot evaluations omit those keys.","additionalProperties":true,"properties":{"mode":{"type":"string","enum":["two_stage"]},"summary":{"type":"string"},"recommendation":{"type":"string"}}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/candidates/{id}":{"get":{"summary":"Get candidate profile","description":"Returns the candidate record, optional partner-provided profile, and all applications visible to the partner. Each application echoes public `metadata` plus resolved `applicationPage` and `hostedBranding` values.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/CandidateId"}],"responses":{"200":{"description":"Candidate profile and applications","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/candidates/{id}/profile":{"put":{"summary":"Upsert partner-provided candidate profile","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/CandidateId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateProfileUpsert"}}}},"responses":{"200":{"description":"Candidate profile upserted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/usage":{"get":{"summary":"Current usage summary","tags":["Usage"],"responses":{"200":{"description":"Current month usage","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/usage/history":{"get":{"summary":"Usage history","tags":["Usage"],"parameters":[{"name":"months","in":"query","schema":{"type":"integer","default":6,"minimum":1,"maximum":24}}],"responses":{"200":{"description":"Usage history","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/balance":{"get":{"summary":"Current balance","tags":["Usage"],"responses":{"200":{"description":"Balance and auto-topup settings","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/interview-training/sessions":{"post":{"summary":"Create interview training session","description":"Creates a job-posting-based interview practice session from a project, job offer, or raw posting text.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTrainingSessionCreate"}}}},"responses":{"201":{"description":"Interview training session created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InterviewTrainingSession"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/interview-training/sessions/{id}":{"get":{"summary":"Get interview training session","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"}],"responses":{"200":{"description":"Interview training session","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/InterviewTrainingSession"},{"type":"object","properties":{"answers":{"type":"array","items":{"$ref":"#/components/schemas/InterviewTrainingAnswer"}},"progress":{"$ref":"#/components/schemas/InterviewTrainingProgress"}}}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/interview-training/sessions/{id}/next-question":{"get":{"summary":"Get next interview training question","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"}],"responses":{"200":{"description":"Next unanswered question","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"question":{"anyOf":[{"$ref":"#/components/schemas/InterviewTrainingQuestion"},{"type":"null"}]},"progress":{"$ref":"#/components/schemas/InterviewTrainingProgress"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/interview-training/sessions/{id}/answers":{"post":{"summary":"Submit interview training answer","description":"Stores a candidate practice answer and returns coaching feedback.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTrainingAnswerCreate"}}}},"responses":{"200":{"description":"Answer feedback","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"answer":{"$ref":"#/components/schemas/InterviewTrainingAnswer"},"feedback":{"$ref":"#/components/schemas/InterviewTrainingFeedback"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/interview-training/sessions/{id}/summary":{"post":{"summary":"Generate interview training summary","description":"Generates or returns a cached final readiness report for the practice session.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Training summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"$ref":"#/components/schemas/InterviewTrainingSummary"},"cached":{"type":"boolean"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/webhooks":{"get":{"summary":"List webhooks","tags":["Webhooks"],"responses":{"200":{"description":"Webhook registrations","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"summary":"Create webhook","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"Public HTTPS webhook URL. Localhost and private/link-local/reserved IP targets are rejected."},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"secret":{"type":"string"}}}}}},"responses":{"200":{"description":"Webhook created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/webhooks/{id}":{"put":{"summary":"Update webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Public HTTPS webhook URL. Localhost and private/link-local/reserved IP targets are rejected."},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Delete webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/webhooks/{id}/deliveries":{"get":{"summary":"List webhook deliveries","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Webhook delivery log","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/webhooks/test":{"post":{"summary":"Send test webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhookId"],"properties":{"webhookId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"statusCode":{"type":"integer"},"response":{"type":"string","nullable":true},"deliveredAt":{"type":"string","format":"date-time","nullable":true}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}}},"tags":[{"name":"Health","description":"Operational health and dependency readiness","x-displayName":"Health"},{"name":"Projects","description":"Recruitment projects and AI-generated pipelines","x-displayName":"Projects"},{"name":"Candidates","description":"Candidate invitations and profiles","x-displayName":"Candidates"},{"name":"Applications","description":"Application status, recordings, and evaluations","x-displayName":"Applications"},{"name":"Usage","description":"Usage, billing, and balance insights","x-displayName":"Usage"},{"name":"Interview Training","description":"Job-posting-based practice interviews for embedded partner flows","x-displayName":"Interview Training"},{"name":"Webhooks","description":"Webhook registration and delivery tracking","x-displayName":"Webhooks"}]}