{"openapi":"3.1.0","info":{"title":"JobMojito API","version":"1.0.0","description":"Public API for JobMojito, served by Supabase Edge Functions. Authenticate with a Supabase JWT access token via the Authorization header."},"servers":[{"url":"https://cool.jobmojito.com/functions/v1","description":"Production"}],"tags":[{"name":"Interviews","description":"Create, configure and manage interview / coaching / assessment definitions."},{"name":"Results","description":"Interview results, transcripts, reports, re-attempt requests and analytics."},{"name":"Candidates","description":"List and manage candidates."},{"name":"Knowledge base","description":"Upload documents used to generate knowledge-base interviews."},{"name":"Resume & Form verification","description":"Pre-screen candidates from resumes and forms."},{"name":"Admin","description":"Account administration — invite team/coaching users, manage sub-merchants and avatar templates."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Supabase JWT access token, passed as `Authorization: Bearer <token>`."}},"schemas":{"JobInterviewCreateResponse":{"type":"object","properties":{"interview_def_set_id":{"type":"string","description":"Id of the newly created interview definition set.","example":"00000000-0000-0000-0000-000000000000"},"embed_id":{"type":"string","description":"Embed id, present only when is_embedded=true."},"embed_signing_key":{"type":"string","description":"Embed signing key, present only when is_embedded=true."}},"required":["interview_def_set_id"],"description":"Id of the created interview. Includes embed_id/embed_signing_key when is_embedded=true."},"Error":{"type":"object","properties":{"error":{"type":"string","example":"Field is required."},"name":{"type":"string","example":"interview_result_id"}},"required":["error"]},"JobInterviewCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Interview / position name.","example":"Project manager"},"location":{"type":"string","minLength":1,"description":"Job location.","example":"remote"},"interview_template_id":{"type":"string","minLength":1,"format":"uuid","description":"Id of the interview template to base this interview on.","example":"baa3bf7c-6926-46fd-9005-16738a31f72d"},"mojito_language_code":{"type":"string","enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Platform language code used for the interview. Must be one of the platform-languages.json codes.","example":"en"},"status":{"type":"string","enum":["draft","active"],"description":"Lifecycle status of the interview. Options — `draft`: Created but not published — not visible to candidates and cannot be run yet. Use to stage an interview before going live. | `active`: Published and live — candidates can run it..","example":"active"},"type":{"type":"string","enum":["interview","coaching","assessment"],"description":"Product type of the interview. Options — `interview`: Standard candidate interview for a role — answers are AI-scored and produce a hiring recommendation. | `coaching`: Practice/coaching session — candidate-facing feedback to help them improve; not a hiring evaluation. Only available on the coaching portal, NOT the interview portal. | `assessment`: Skills/knowledge assessment — evaluates competencies and is scored like an interview..","example":"interview"},"visibility":{"type":"string","enum":["merchant_public","merchant_invite","merchant_unlisted"],"description":"Who can discover and access the interview. Options — `merchant_public`: Listed on the merchant's public interview list — anyone with the merchant link can find and start it. | `merchant_invite`: Invite-only — only candidates explicitly invited (by email/link) can access it; not listed anywhere. | `merchant_unlisted`: Reachable only via a direct link — not listed anywhere; share the link manually..","example":"merchant_public"},"recording":{"type":"string","nullable":true,"enum":["audio_first_5_answers","audio_all","video_all","video_first_5_answers"],"description":"Cheating/proctoring detection mode for candidate answers — this is NOT a full session recording. Video options also record the candidate. Omit/null to disable. Options — `audio_first_5_answers`: Audio-only cheating detection, first 5 answers only. | `audio_all`: Audio-only cheating detection on every answer. | `video_all`: Audio + video cheating detection on every answer (candidate is recorded for all answers). | `video_first_5_answers`: Audio + video cheating detection, first 5 answers only..","example":"video_all"},"recording_full_session":{"type":"string","nullable":true,"enum":["audio_all","video_all"],"description":"Full interview-session recording (includes the avatar and voice) produced as a single file. Independent of `recording`. Omit/null to disable. Options — `audio_all`: Record the whole session audio (avatar + candidate voice) into a single file. Adds +0.2 credits. | `video_all`: Record the whole session video + audio (avatar + candidate) into a single file. Adds +0.4 credits..","example":"video_all"},"interview_type":{"type":"string","enum":["pre-screening","pre-screening-with-test-questions","second-interview","remote-freelancer-verification","strength-based-interview","potential-based-interview","process-verification-from-knowledge-base"],"description":"Interview style — configures the AI avatar and shapes both the AI-generated questions and the follow-up questions asked during the interview. Defaults to pre-screening when omitted. Options — `pre-screening`: Pre-screening — quick qualification check focusing on basic requirements and availability. | `pre-screening-with-test-questions`: Pre-screening with test questions — pre-screening plus practical questions to test relevant skills. | `second-interview`: Second round interview — deeper dive for candidates who passed initial screening. | `remote-freelancer-verification`: Remote worker verification — verify remote work capabilities and communication skills. | `strength-based-interview`: Strength-based interview — focus on what candidates enjoy and excel at to predict job satisfaction. | `potential-based-interview`: Potential-based interview — assess learning ability and growth potential rather than past experience. | `process-verification-from-knowledge-base`: Knowledge Base interview — generate questions from your knowledge base documents..","example":"pre-screening-with-test-questions"},"seniority_level":{"type":"string","nullable":true,"enum":["entry-level","intermediate","senior","managerial","director","executive"],"description":"Target seniority level for the role; auto-detected from the job description when omitted. Options — `entry-level`: Early-career or graduate roles. | `intermediate`: Some experience required. | `senior`: Experienced professional. | `managerial`: Team or department lead. | `director`: Director-level responsibility. | `executive`: C-suite or executive role..","example":"senior"},"result_view":{"type":"string","nullable":true,"enum":["none","minimal","minimal_with_score","advanced","full","full_expand_scores"],"description":"Result screen shown to the candidate after finishing. With any value other than `none`, the candidate sees a results screen where they can provide feedback, record an intro video and edit the transcript, and must then submit the result; the value sets how much score/result detail is shown. Options — `none`: No results screen at all — the interview is submitted immediately when the candidate finishes (no feedback, intro video, transcript edit or manual submit step). | `minimal`: Minimal results layout, no score shown. | `minimal_with_score`: Minimal results layout including the overall score. | `advanced`: Advanced results layout with more detail. | `full`: Full results layout with all sections. | `full_expand_scores`: Full results with every score breakdown expanded..","example":"full"},"candidate_video_introduction":{"type":"string","nullable":true,"enum":["optional","required"],"description":"Whether a candidate video introduction is optional or required.","example":"optional"},"interview_tone":{"type":"string","nullable":true,"description":"Interview tone — configures the AI avatar's speaking style and the tone of the AI-generated questions and follow-ups; omit to default to relaxed. Suggested values — `relaxed`: Friendly and conversational tone that helps candidates feel at ease. | `simple`: Plain language at CEFR A2 level — short sentences and simple words. | `professional`: Formal and business-like approach suitable for senior roles. | `persuasive`: Engaging style that encourages candidates to elaborate.. Case-insensitive; other strings are accepted but unknown tones fall back to the default.","example":"professional"},"interview_length":{"anyOf":[{"type":"number"},{"type":"string"},{"nullable":true}],"description":"Number of questions to generate (max 40).","example":8},"interview_attempts":{"type":"number","nullable":true,"minimum":1,"maximum":20,"description":"Allowed candidate attempts (1-20).","example":1},"max_duration":{"type":"number","nullable":true,"description":"Maximum interview duration in minutes used to scope question generation.","example":30},"code":{"type":"string","nullable":true,"description":"Optional external code/reference for the interview.","example":"my code"},"cover_image_url":{"type":"string","nullable":true,"description":"Cover image URL.","example":"https://example.com/cover.png"},"merchant_id":{"type":"string","nullable":true,"description":"Merchant id. Only honored for admin or sub-merchant callers; otherwise taken from the JWT.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"knowledge_base_store_id":{"type":"string","nullable":true,"description":"Knowledge base store id to source additional context from."},"description":{"type":"string","nullable":true,"description":"Short job description (regenerated by AI)."},"description_long":{"type":"string","nullable":true,"description":"Long job description."},"candidate_expectations":{"type":"string","nullable":true,"description":"Free-text candidate expectations folded into AI generation."},"welcome_message":{"type":"string","nullable":true,"description":"Custom welcome message shown to the candidate."},"thank_you_message":{"type":"string","nullable":true,"description":"Custom thank-you message shown after the interview."},"additional_context":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Arbitrary additional context object merged into AI generation."},"instructional_video_custom_text":{"type":"string","nullable":true,"description":"Custom narration text for the instructional video."},"is_embedded":{"type":"boolean","nullable":true,"description":"Set true when the interview will be embedded as an iframe on an external page. Provisions an embed key and returns embed_id / embed_signing_key, which are used to authenticate/sign the iframe embed.","example":false},"include_rapport_question":{"type":"boolean","nullable":true,"description":"Include an opening rapport question. Defaults to false.","example":true},"include_closing_prompt":{"type":"boolean","nullable":true,"description":"Include a closing prompt. Defaults to true.","example":true},"instructional_video":{"type":"boolean","nullable":true,"description":"Show an instructional video before approval. Defaults to false.","example":true},"use_enhanced_expectations":{"type":"boolean","nullable":true,"description":"Reserved flag passed through to generation."},"custom_scoring":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Custom result-scoring overrides merged with defaults and template overrides."}},"required":["name","location","interview_template_id","mojito_language_code","status","type","visibility"]},"JobInterviewCreateFromArrayResponse":{"type":"object","properties":{"interview_def_set_id":{"type":"string","description":"Id of the newly created interview definition set."},"embed_id":{"type":"string","description":"Embed id, present only when is_embedded=true."},"embed_signing_key":{"type":"string","description":"Embed signing key, present only when is_embedded=true."}},"required":["interview_def_set_id"],"description":"The created interview definition set id, plus embed credentials when is_embedded=true."},"JobInterviewCreateFromArrayQuestion":{"type":"object","properties":{"question":{"type":"string","description":"The question text shown to the candidate."},"id":{"type":"string","description":"Caller-local identifier for this question. Only needed when another question references it via conditional_question_main_id (the mapping is resolved within this array)."},"duration":{"type":"number","nullable":true,"description":"Answer duration in seconds for this question."},"mojito_language_code":{"type":"string","nullable":true,"enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Per-question language override (one of the platform-languages.json codes). Inherits the interview language when omitted.","example":"en"},"label":{"type":"string","nullable":true,"description":"Optional label/tag stored on the question."},"is_conditional":{"type":"boolean","nullable":true,"description":"Conditional follow-up question (view 'with listening conditional'). Use with conditional_question_main_id."},"is_without_scoring":{"type":"boolean","nullable":true,"description":"Question is asked but not scored (view 'without scoring')."},"is_candidate_asking_recruiter":{"type":"boolean","nullable":true,"description":"Candidate-asks-recruiter prompt (view 'candidate asking recruiter')."},"is_expert":{"type":"boolean","nullable":true,"description":"Expert listening question (view 'with listening expert')."},"is_multiple_choice":{"type":"boolean","nullable":true,"description":"Multiple-choice question (view 'multiple choice')."},"question_alternatives":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Alternative phrasings for the question."},"conditional_question_main_id":{"type":"string","nullable":true,"description":"For a conditional question, the id (the local \"id\" field above) of the parent question in this same array that triggers it."},"knowledge_base_id":{"type":"string","nullable":true,"description":"Knowledge-base store id (uuid) the question draws context from."},"external_id":{"type":"string","nullable":true,"description":"External identifier stored on the question."},"external_data":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Arbitrary JSON metadata stored on the question."},"candidate_expectations_json":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Per-question candidate expectations object."}},"required":["question"],"additionalProperties":{"nullable":true}},"JobInterviewCreateFromArrayRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Interview/position name.","example":"Project manager"},"location":{"type":"string","minLength":1,"description":"Interview location.","example":"remote"},"interview_template_id":{"type":"string","minLength":1,"description":"Id of the interview template to use. Must reference an existing interview_templates row.","example":"46b98d37-1557-4391-beca-03037ead19f2"},"mojito_language_code":{"type":"string","enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Platform language code (one of the platform-languages.json codes); must also resolve to a supported language with an Azure speech mapping.","example":"en"},"description":{"type":"string","minLength":1,"description":"Short interview description.","example":"Project manager role"},"status":{"type":"string","enum":["draft","active"],"description":"Lifecycle status of the interview. Options — `draft`: Created but not published — not visible to candidates and cannot be run yet. Use to stage an interview before going live. | `active`: Published and live — candidates can run it..","example":"active"},"type":{"type":"string","enum":["interview","coaching","assessment"],"description":"Product type of the interview. Options — `interview`: Standard candidate interview for a role — answers are AI-scored and produce a hiring recommendation. | `coaching`: Practice/coaching session — candidate-facing feedback to help them improve; not a hiring evaluation. Only available on the coaching portal, NOT the interview portal. | `assessment`: Skills/knowledge assessment — evaluates competencies and is scored like an interview..","example":"interview"},"visibility":{"type":"string","enum":["merchant_public","merchant_invite","merchant_unlisted"],"description":"Who can discover and access the interview. Options — `merchant_public`: Listed on the merchant's public interview list — anyone with the merchant link can find and start it. | `merchant_invite`: Invite-only — only candidates explicitly invited (by email/link) can access it; not listed anywhere. | `merchant_unlisted`: Reachable only via a direct link — not listed anywhere; share the link manually..","example":"merchant_public"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/JobInterviewCreateFromArrayQuestion"},"minItems":1,"description":"Ordered list of interview questions to create as steps."},"recording":{"type":"string","nullable":true,"enum":["audio_first_5_answers","audio_all","video_all","video_first_5_answers"],"description":"Cheating/proctoring detection mode for candidate answers — this is NOT a full session recording. Video options also record the candidate. Omit/null to disable. Options — `audio_first_5_answers`: Audio-only cheating detection, first 5 answers only. | `audio_all`: Audio-only cheating detection on every answer. | `video_all`: Audio + video cheating detection on every answer (candidate is recorded for all answers). | `video_first_5_answers`: Audio + video cheating detection, first 5 answers only..","example":"video_all"},"recording_full_session":{"type":"string","nullable":true,"enum":["audio_all","video_all"],"description":"Full interview-session recording (includes the avatar and voice) produced as a single file. Independent of `recording`. Omit/null to disable. Options — `audio_all`: Record the whole session audio (avatar + candidate voice) into a single file. Adds +0.2 credits. | `video_all`: Record the whole session video + audio (avatar + candidate) into a single file. Adds +0.4 credits..","example":"video_all"},"interview_type":{"type":"string","nullable":true,"enum":["pre-screening","pre-screening-with-test-questions","second-interview","remote-freelancer-verification","strength-based-interview","potential-based-interview","process-verification-from-knowledge-base"],"description":"Interview style — configures the AI avatar and the follow-up questions it generates during the interview. The base `questions` you supply are used as-is and are NOT affected by this setting. Options — `pre-screening`: Pre-screening — quick qualification check focusing on basic requirements and availability. | `pre-screening-with-test-questions`: Pre-screening with test questions — pre-screening plus practical questions to test relevant skills. | `second-interview`: Second round interview — deeper dive for candidates who passed initial screening. | `remote-freelancer-verification`: Remote worker verification — verify remote work capabilities and communication skills. | `strength-based-interview`: Strength-based interview — focus on what candidates enjoy and excel at to predict job satisfaction. | `potential-based-interview`: Potential-based interview — assess learning ability and growth potential rather than past experience. | `process-verification-from-knowledge-base`: Knowledge Base interview — generate questions from your knowledge base documents..","example":"pre-screening-with-test-questions"},"seniority_level":{"type":"string","nullable":true,"enum":["entry-level","intermediate","senior","managerial","director","executive"],"description":"Target seniority level for the role; auto-detected from the job description when omitted. Options — `entry-level`: Early-career or graduate roles. | `intermediate`: Some experience required. | `senior`: Experienced professional. | `managerial`: Team or department lead. | `director`: Director-level responsibility. | `executive`: C-suite or executive role..","example":"senior"},"result_view":{"type":"string","nullable":true,"enum":["none","minimal","minimal_with_score","advanced","full","full_expand_scores"],"description":"Result screen shown to the candidate after finishing. With any value other than `none`, the candidate sees a results screen where they can provide feedback, record an intro video and edit the transcript, and must then submit the result; the value sets how much score/result detail is shown. Options — `none`: No results screen at all — the interview is submitted immediately when the candidate finishes (no feedback, intro video, transcript edit or manual submit step). | `minimal`: Minimal results layout, no score shown. | `minimal_with_score`: Minimal results layout including the overall score. | `advanced`: Advanced results layout with more detail. | `full`: Full results layout with all sections. | `full_expand_scores`: Full results with every score breakdown expanded..","example":"full"},"candidate_video_introduction":{"type":"string","nullable":true,"enum":["optional","required"],"description":"Whether a candidate video introduction is optional or required."},"interview_tone":{"type":"string","nullable":true,"description":"Tone — configures the AI avatar's speaking style and the follow-up questions it generates; the base `questions` you supply are not affected. Omit to default to relaxed. Suggested values — `relaxed`: Friendly and conversational tone that helps candidates feel at ease. | `simple`: Plain language at CEFR A2 level — short sentences and simple words. | `professional`: Formal and business-like approach suitable for senior roles. | `persuasive`: Engaging style that encourages candidates to elaborate.. Case-insensitive; other strings are accepted but unknown tones fall back to the default.","example":"professional"},"interview_attempts":{"type":"number","nullable":true,"description":"Allowed attempts, 1-20.","example":1},"questions_random_subset":{"type":"number","nullable":true,"description":"Fraction of questions to randomly ask, between 0.01 and 0.9."},"code":{"type":"string","nullable":true,"description":"Optional external code/reference."},"cover_image_url":{"type":"string","nullable":true,"description":"Cover image URL."},"knowledge_base_store_id":{"type":"string","nullable":true,"description":"Optional knowledge base store id; validated for existence."},"merchant_id":{"type":"string","nullable":true,"description":"Target merchant id (admins / sub-merchant only)."},"description_long":{"type":"string","nullable":true,"description":"Long-form interview description."},"candidate_expectations":{"type":"string","nullable":true,"description":"Free-text candidate expectations."},"candidate_expectations_json":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Pre-generated candidate expectations object; auto-generated when omitted for type=interview."},"custom_scoring":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Custom scoring overrides merged with defaults."},"additional_context":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Extra context forwarded to expectation generation."},"instructional_video":{"type":"boolean","nullable":true,"description":"Enable an instructional video before approval."},"instructional_video_custom_text":{"type":"string","nullable":true,"description":"Custom text for the instructional video."},"disable_deduplication":{"type":"boolean","nullable":true,"description":"When true, skip step deduplication on insert."},"welcome_message":{"type":"string","nullable":true,"description":"Custom welcome message."},"thank_you_message":{"type":"string","nullable":true,"description":"Custom thank-you message."},"is_embedded":{"type":"boolean","nullable":true,"description":"Set true when the interview will be embedded as an iframe on an external page. Creates an embed key and returns embed_id/embed_signing_key, used to authenticate/sign the iframe embed."}},"required":["name","location","interview_template_id","mojito_language_code","description","status","type","visibility","questions"]},"JobInterviewCreateForCandidateWithTokenResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ai_accept","recruiter_accept","recruiter_action","ai_reject","recruiter_reject","already-applied"],"description":"Decision / lifecycle status for the candidate against this position."},"position_def_set_id":{"type":"string","description":"Created/resolved position id."},"interview_def_set_id":{"type":"string","description":"Created/resolved interview definition set id."},"profile_interview_id":{"type":"string","description":"Candidate profile_interview id."},"interview_url":{"type":"string","description":"URL the candidate should open to continue."},"reason":{"type":"string","description":"Human-readable reason, present on reject / already-applied branches."},"embed_id":{"type":"string","description":"Embed id, present only when is_embedded=true."},"embed_signing_key":{"type":"string","description":"Embed signing key, present only when is_embedded=true."}},"required":["status","interview_url"],"description":"Result of creating (or resolving) the position and enrolling the candidate. Fields present depend on the decision branch."},"JobInterviewCreateForCandidateWithTokenRequest":{"type":"object","properties":{"position_def_set_id":{"type":"string","nullable":true,"description":"Existing position_def_set id. When provided, the position is looked up instead of created, and position_name/position_location/position_country_code/mojito_language_code become optional.","example":"00000000-0000-0000-0000-000000000000"},"position_external_id":{"type":"string","nullable":true,"description":"External position code used to look up an existing position.","example":"JOB-123"},"interview_template_id":{"type":"string","nullable":true,"description":"Interview template id to base the interview on. Defaults to the platform template when omitted.","example":"5d8ea38b-eec4-4866-aa6c-b2ea5bc6e45b"},"merchant_id":{"type":"string","nullable":true,"description":"Merchant id. Only honoured for admin / sub-merchant tokens; otherwise the token merchant is used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"position_name":{"type":"string","nullable":true,"description":"Position / job title. Required when position_def_set_id is not provided.","example":"Entry level coffee boy"},"position_location":{"type":"string","nullable":true,"description":"Position location. Required when position_def_set_id is not provided.","example":"remote"},"position_country_code":{"type":"string","nullable":true,"description":"ISO country code of the position. Required when position_def_set_id is not provided.","example":"SK"},"mojito_language_code":{"type":"string","nullable":true,"enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Interview language code (one of the platform-languages.json codes). Required when position_def_set_id is not provided.","example":"en"},"position_description":{"type":"string","nullable":true,"description":"Short position description."},"position_description_long":{"type":"string","nullable":true,"description":"Full / long position description."},"candidate_name":{"type":"string","minLength":1,"description":"Candidate full name.","example":"John"},"candidate_email":{"type":"string","minLength":1,"description":"Candidate email (used as auth identity).","example":"peterson6@hello.com"},"candidate_country_code":{"type":"string","minLength":1,"description":"ISO country code of the candidate.","example":"HR"},"candidate_resume":{"type":"string","minLength":1,"description":"Candidate resume parsed text.","example":"Curriculum Vitae ..."},"candidate_external_id":{"type":"string","nullable":true,"description":"External candidate id stored on the profile."},"candidate_linkedin_url":{"type":"string","nullable":true,"description":"Candidate LinkedIn URL."},"candidate_video_introduction":{"type":"string","nullable":true,"enum":["optional","required"],"description":"Whether a candidate video introduction is optional or required."},"interview_attempts":{"type":"number","nullable":true,"minimum":1,"maximum":20,"description":"Number of allowed interview attempts (1-20).","example":3},"seniority_level":{"type":"string","nullable":true,"enum":["entry-level","intermediate","senior","managerial","director","executive"],"description":"Seniority level of the position. Auto-detected when omitted."},"result_view":{"type":"string","nullable":true,"enum":["none","minimal","minimal_with_score","advanced","full","full_expand_scores"],"description":"How interview results are shown to the candidate. Defaults to minimal."},"custom_scoring":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Optional custom scoring overrides merged with platform defaults."},"use_enhanced_expectations":{"type":"boolean","nullable":true,"description":"Reserved flag for enhanced candidate expectations generation."},"include_rapport_question":{"type":"boolean","nullable":true,"description":"Include an opening rapport question. Defaults to false."},"include_closing_prompt":{"type":"boolean","nullable":true,"description":"Include a closing prompt. Defaults to true."},"instructional_video":{"type":"boolean","nullable":true,"description":"Show an instructional video before the interview. Defaults to false."},"instructional_video_custom_text":{"type":"string","nullable":true,"description":"Custom text shown with the instructional video."},"welcome_message":{"type":"string","nullable":true,"description":"Custom welcome message for the interview."},"thank_you_message":{"type":"string","nullable":true,"description":"Custom thank-you message shown after the interview."},"max_duration":{"type":"number","nullable":true,"description":"Maximum interview duration used to scale generated questions."},"is_embedded":{"type":"boolean","nullable":true,"description":"Set true when the interview will be embedded as an iframe on an external page. Ensures an embed key exists and returns embed_id/embed_signing_key, used to authenticate/sign the iframe embed."}},"required":["candidate_name","candidate_email","candidate_country_code","candidate_resume"]},"JobInterviewGetResponse":{"type":"object","properties":{"name":{"type":"string","nullable":true,"description":"Interview or position name."},"created_at":{"type":"string","nullable":true,"example":"2026-01-15T09:30:00.000Z"},"updated_at":{"type":"string","nullable":true,"example":"2026-01-20T14:05:00.000Z"},"calc_definition_json":{"nullable":true,"description":"The compiled interview definition JSON (structure varies by interview type)."},"is_multistage":{"type":"boolean","description":"True when the id resolved to a multi-stage position rather than a single interview."}},"required":["name","created_at","updated_at","is_multistage"]},"JobInterviewSetStateResponse":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},{"type":"object","properties":{"embed_id":{"type":"string"},"embed_signing_key":{"type":"string"}},"required":["embed_id","embed_signing_key"]}],"description":"Returns `{ embed_id, embed_signing_key }` when an embed key was created/returned (is_embedded=true), otherwise `{ success: true }`."},"JobInterviewSetStateRequest":{"type":"object","properties":{"position_id":{"type":"string","minLength":1,"format":"uuid","description":"Interview definition id or position id whose state should change.","example":"00000000-0000-0000-0000-000000000000"},"status":{"type":"string","nullable":true,"enum":["draft","active","archived","deleted","preparing","completed"],"description":"New lifecycle status to apply."},"is_embedded":{"type":"boolean","nullable":true,"description":"Controls iframe embedding of the interview on an external page. When true, ensures an embed key exists (returns embed_id/embed_signing_key, used to authenticate/sign the iframe embed). When false, removes the embed keys (disables embedding)."}},"required":["position_id"]},"JobInterviewTokenResponse":{"type":"string","description":"The signed interview URL.","example":"https://interviews.example.com/interview/take/<id>/?interview_token=<jwt>&view_hm=true"},"JobInterviewTokenRequest":{"type":"object","properties":{"type":{"type":"string","enum":["interview-for-profile","results-for-profile","interview-result-candidate","interview-result-talent-seeker","interview-results-for-position"],"description":"Which kind of signed URL to generate."},"merchant_id":{"type":"string","description":"Override merchant id (admin / sub-merchant only)."},"interview_profile_id":{"type":"string","description":"Candidate profile id. Required for interview-for-profile and results-for-profile."},"interview_id":{"type":"string","description":"Interview or position id. Required for interview-for-profile and interview-results-for-position."},"interview_result_id":{"type":"string","description":"Interview result id. Required for interview-result-candidate and interview-result-talent-seeker."},"hide_menu":{"anyOf":[{"type":"string"},{"type":"boolean"}],"description":"Pass the string 'false' to show the navigation menu; any other value hides it (default)."}},"required":["type"]},"JobInterviewRegisterUsersResponse":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","nullable":true},"email":{"type":"string"},"external_id":{"type":"string","nullable":true},"result":{"type":"string","description":"\"ok\" on success, otherwise an \"Error: ...\" message for that user.","example":"ok"},"interview_url":{"type":"string","description":"One-time interview URL containing the minted interview_token. Present only on success."}},"additionalProperties":{"nullable":true}},"description":"The input users, each annotated with its registration result and (on success) interview URL."},"RegisterUser":{"type":"object","properties":{"name":{"type":"string","nullable":true,"description":"Display name of the candidate.","example":"Peter Parker"},"email":{"type":"string","nullable":true,"description":"Email used to identify and invite the candidate. Validated per item, not request-level.","example":"jozo@jozo.sk"},"external_id":{"type":"string","nullable":true,"description":"Optional caller-supplied id, stored on the candidate profile.","example":"abcd"}}},"JobInterviewRegisterUsersRequest":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/RegisterUser"},"description":"Candidates to register for the interview. Each gets a one-time interview URL.","example":[{"name":"Peter Parker","email":"jozo@jozo.sk","external_id":"abcd"},{"name":"mr beast","email":"hi@jozefbalaz.com"}]},"interview_id":{"type":"string","minLength":1,"format":"uuid","description":"Interview definition (interview_def_set) or position (position_def_set) id to register users for.","example":"04e09fa5-3fb8-4236-b37d-fca2bcd1cb66"},"merchant_id":{"type":"string","nullable":true,"format":"uuid","description":"Merchant id. Required when authenticating with the service key; for user tokens it is optional and only honored for admin / sub-merchant accounts.","example":"b5201178-46dd-4a20-a1af-7ffd647f834b"},"send_email":{"type":"boolean","nullable":true,"description":"Whether to send an invitation email to each registered candidate."},"hide_menu":{"anyOf":[{"type":"boolean"},{"type":"string"},{"nullable":true}],"description":"When true (or the string \"true\"), the interview UI hides its menu (view_hm)."},"hide_iframe":{"anyOf":[{"type":"boolean"},{"type":"string"},{"nullable":true}],"description":"When true (or the string \"true\"), the interview UI hides its iframe chrome (view_hi)."},"is_test":{"anyOf":[{"type":"boolean"},{"type":"string"},{"nullable":true}],"description":"When true (or the string \"true\"), mints a test token that can take a draft/unpublished interview and flags the result as a test."}},"required":["users","interview_id"]},"Pagination":{"type":"object","properties":{"total":{"type":"integer","description":"Total matching records across all pages.","example":137},"limit":{"type":"integer","description":"Page size used for this response.","example":50},"offset":{"type":"integer","description":"Offset used for this response.","example":0},"has_more":{"type":"boolean","description":"True when more records exist beyond this page (offset + returned < total).","example":true}},"required":["total","limit","offset","has_more"]},"MerchantInterviewListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Interview definition id."},"merchant_id":{"type":"string","nullable":true,"description":"Owning merchant id."},"name":{"type":"string","nullable":true,"description":"Interview name."},"emoji":{"type":"string","nullable":true,"description":"Emoji marker."},"type":{"type":"string","nullable":true,"description":"Product type (interview/coaching/…)."},"type_avatar":{"type":"string","nullable":true,"description":"Avatar type used by the interview."},"status":{"type":"string","nullable":true,"description":"Lifecycle status."},"visibility":{"type":"string","nullable":true,"description":"Visibility (merchant_public/invite/unlisted/…)."},"mojito_language_code":{"type":"string","nullable":true,"description":"Platform language code."},"speech_language_code":{"type":"string","nullable":true,"description":"Speech language code."},"environment":{"type":"string","nullable":true,"description":"Environment (production/test/…)."},"is_ats":{"type":"boolean","nullable":true,"description":"Whether the interview is ATS-integrated."},"is_multi_stage":{"type":"boolean","nullable":true,"description":"Whether the interview is multi-stage."},"recording":{"type":"string","nullable":true,"description":"Per-answer recording/proctoring mode."},"recording_full_session":{"type":"string","nullable":true,"description":"Full-session recording mode."},"billing_single_position":{"type":"boolean","nullable":true,"description":"Single-position billing flag."},"billing_single_position_end_at":{"type":"string","nullable":true,"description":"Single-position billing end (ISO 8601)."},"cover_image_url":{"type":"string","nullable":true,"description":"Cover image URL."},"interview_count":{"type":"number","nullable":true,"description":"Number of interviews run against this definition."},"interview_last":{"type":"string","nullable":true,"description":"Timestamp of the most recent interview (ISO 8601)."},"calc_duration":{"type":"number","nullable":true,"description":"Calculated duration."},"created_at":{"type":"string","nullable":true,"description":"Creation timestamp (ISO 8601)."},"updated_at":{"type":"string","nullable":true,"description":"Last update timestamp (ISO 8601)."}},"required":["id"],"additionalProperties":{"nullable":true}},"description":"The merchant's interview definitions for this page, newest-updated first."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"JobInterviewDetailsResponse":{"type":"object","properties":{"score":{"type":"number","nullable":true,"description":"Overall interview score."},"score_simulation":{"type":"number","nullable":true,"description":"Overall simulated score."},"score_text":{"type":"string","nullable":true,"description":"Human-readable score summary."},"score_sentiment":{"type":"number","nullable":true,"description":"Sentiment sub-score."},"score_words_per_minute":{"type":"number","nullable":true,"description":"Speaking-pace (words per minute) sub-score."},"score_pronunciation":{"type":"number","nullable":true,"description":"Pronunciation sub-score."},"score_answer":{"type":"number","nullable":true,"description":"Aggregate answer sub-score."},"status":{"type":"string","nullable":true,"description":"Coach/interview status (coach_status), e.g. started, completed."},"start":{"type":"string","nullable":true,"description":"Interview start timestamp (training_start, ISO 8601)."},"end":{"type":"string","nullable":true,"description":"Interview end timestamp (training_end, ISO 8601)."},"duration":{"type":"number","nullable":true,"description":"Total duration in deciseconds (duration_ds)."},"ai_interview_coverage_percentage":{"type":"number","nullable":true,"description":"Percentage of the intended interview the AI judged to be covered."},"ai_completion_reason":{"type":"string","nullable":true,"description":"Why the interview completed (ai_completed_reason)."},"ai_analysis":{"type":"string","nullable":true,"description":"Candidate-facing AI analysis of the whole interview."},"ai_analysis_recruiter":{"type":"string","nullable":true,"description":"Recruiter-facing AI analysis of the whole interview."},"ai_analysis_recruiter_why_hire":{"nullable":true,"description":"Reasons to hire (list/text)."},"ai_analysis_recruiter_why_not_hire":{"nullable":true,"description":"Reasons not to hire (list/text)."},"recruiter_risks":{"nullable":true,"description":"Detected recruiter risk flags (jsonb)."},"user_feedback_recruiter":{"type":"string","nullable":true,"description":"Recruiter-entered feedback note."},"recording_local_path":{"type":"string","nullable":true,"description":"Storage path of the full session recording."},"recording_is_video":{"type":"boolean","nullable":true,"description":"Whether the session recording is video."},"video_introduction_local_path":{"type":"string","nullable":true,"description":"Storage path of the candidate video introduction."},"recording_url":{"type":"string","nullable":true,"description":"Signed session-recording URL; present only when get_signed_recordings=true."},"video_introduction_url":{"type":"string","nullable":true,"description":"Signed video-introduction URL; present only when get_signed_recordings=true."},"transcript":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"interview_result_question id."},"is_answer":{"type":"boolean","description":"True for a candidate answer turn, false for an avatar/question turn."},"view":{"type":"string","nullable":true,"description":"Question view/type (e.g. with listening, multiple choice, without scoring)."},"question_original_id":{"type":"string","nullable":true,"description":"Source interview_def_question id (null for generated follow-ups)."},"question_original":{"type":"string","nullable":true,"description":"Original question text from the definition (when question_original_id is set)."},"question_asked":{"type":"string","nullable":true,"description":"The question text actually asked to the candidate."},"answer":{"type":"string","nullable":true,"description":"The candidate answer transcript text."},"ai_analysis":{"type":"string","nullable":true,"description":"AI analysis of this answer."},"ai_analysis_recruiter":{"type":"string","nullable":true,"description":"Recruiter-facing AI analysis of this answer."},"score":{"type":"number","nullable":true,"description":"Score for this interaction."},"score_simulation":{"type":"number","nullable":true,"description":"Simulated score for this interaction."},"score_answer_ai":{"type":"number","nullable":true,"description":"AI answer score."},"score_answer_ai_simulation":{"type":"number","nullable":true,"description":"Simulated AI answer score."},"duration":{"type":"number","nullable":true,"description":"Duration of this interaction in deciseconds (duration_ds)."},"mojito_language_code":{"type":"string","nullable":true,"description":"Platform language code of this interaction."},"answer_assessment_raw_data":{"nullable":true,"description":"Raw per-answer assessment data (pronunciation/sentiment/etc.)."},"recording_local_path":{"type":"string","nullable":true,"description":"Storage path of this answer recording (private-recordings bucket)."},"recording_is_video":{"type":"boolean","nullable":true,"description":"Whether this answer recording is video (vs audio)."},"external_data":{"nullable":true,"description":"External data carried from the question definition."},"external_id":{"type":"string","nullable":true,"description":"External identifier carried from the question definition."},"recording_url":{"type":"string","nullable":true,"description":"Signed URL for recording_local_path; present only when get_signed_recordings=true."}},"additionalProperties":{"nullable":true}},"description":"Ordered interactions (questions + answers) of the interview."}},"additionalProperties":{"nullable":true},"description":"The interview result with its transcript, produced by the interview_transcript RPC. Additional fields may be present (passthrough)."},"JobInterviewPdfPdfExport":{"type":"object","properties":{"pdf_export_url":{"type":"string","format":"uri","description":"Signed URL of the generated PDF."},"pdf_export_valid_until":{"type":"string","description":"ISO timestamp until which the signed URL is valid.","example":"2026-09-01T12:00:00.000Z"}},"required":["pdf_export_url","pdf_export_valid_until"],"description":"Returned when `export_type` is `pdf`.","title":"PDF export"},"JobInterviewPdfHtmlExport":{"type":"object","properties":{"html_export":{"type":"string","description":"The full report rendered as an HTML document string."}},"required":["html_export"],"description":"Returned when `export_type` is `html`.","title":"HTML export"},"JobInterviewPdfJsonExport":{"type":"object","properties":{"json_export":{"type":"object","properties":{"table":{"type":"string","description":"Overview table HTML, present only for multi-result exports."},"results":{"type":"array","items":{"type":"object","properties":{"data":{"type":"object","additionalProperties":{"nullable":true}},"files":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"page":{"type":"number","nullable":true},"page_signed":{"type":"string","nullable":true}},"required":["type","page","page_signed"]}}},"required":["data","files"]}}},"required":["results"]}},"required":["json_export"],"description":"Returned when `export_type` is `json`.","title":"JSON export"},"JobInterviewPdfResponse":{"anyOf":[{"$ref":"#/components/schemas/JobInterviewPdfPdfExport"},{"$ref":"#/components/schemas/JobInterviewPdfHtmlExport"},{"$ref":"#/components/schemas/JobInterviewPdfJsonExport"}],"description":"The generated report. Exactly one of the three shapes below is returned, selected by the request `export_type`: `pdf` → `{ pdf_export_url, pdf_export_valid_until }`; `html` → `{ html_export }`; `json` → `{ json_export }`."},"InterviewPdfExportFeatures":{"type":"object","properties":{"mojito_language_code":{"type":"string","enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Report language. Optional: if omitted, the report uses each result's own language code. If provided and it differs from the result's language, the report content is translated, which costs 0.1 credit per result.","example":"en"},"contact_details":{"type":"boolean","default":true,"description":"Include the candidate's contact details (email, LinkedIn, phone number, physical address)."},"ai_recruiter_assessment":{"type":"boolean","default":true,"description":"Include the AI recruiter assessment: resume analysis, overall AI analysis, and the why-hire / why-not-hire summaries."},"ai_scoring_rubric":{"type":"boolean","default":false,"description":"Include the AI scoring rubric — the candidate-expectation buckets (strong / moderate / weak). Only takes effect when ai_recruiter_assessment is also true."},"analytics":{"type":"boolean","default":true,"description":"Include speech analytics for each answer (speech accuracy, fluency, recognition confidence, sentiment, cadence / words-per-minute)."},"transcript":{"type":"boolean","default":true,"description":"Include the full interview transcript: each question, the candidate answer, and the per-answer AI analysis."},"files":{"type":"boolean","default":true,"description":"Include the candidate's uploaded files (resume and cover letter) as signed page URLs."},"answer_recording":{"type":"boolean","default":false,"description":"Include a signed recording URL (audio/video) for each individual answer."},"session_recording":{"type":"boolean","default":false,"description":"Include the full interview session recording and the video introduction as signed URLs."},"group_by_question":{"type":"boolean","default":false,"description":"Group answers under their expected questions (instead of chronological order), including questions that were not reached."}}},"JobInterviewPdfRequest":{"type":"object","properties":{"interview_result_id":{"type":"string","format":"uuid","example":"93c98d21-e04d-4a84-9afa-ed154cf73636"},"interview_result_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Generate a single combined report for multiple results."},"export_type":{"type":"string","enum":["pdf","html","json"]},"export_features_result":{"$ref":"#/components/schemas/InterviewPdfExportFeatures"},"store_file":{"type":"boolean","description":"When true (pdf only), persist the file to storage and return a signed URL."}},"required":["export_type"]},"RequestAnotherAttemptResponse":{"type":"object","properties":{},"description":"Empty object on success."},"RequestAnotherAttemptRequest":{"type":"object","properties":{"interview_result_id":{"type":"string","minLength":1,"format":"uuid","description":"The interview result to reopen for another attempt.","example":"93c98d21-e04d-4a84-9afa-ed154cf73636"}},"required":["interview_result_id"]},"MerchantResultListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Position result row id."},"interview_result_id":{"type":"string","nullable":true,"description":"Interview result id (use with merchant-... detail endpoints)."},"interview_result_pre_screening_id":{"type":"string","nullable":true,"description":"Pre-screening result id, if any."},"merchant_id":{"type":"string","nullable":true,"description":"Owning merchant id."},"profile_id":{"type":"string","nullable":true,"description":"Candidate profile id."},"profile_interview_id":{"type":"string","nullable":true,"description":"Candidate (profile_interview) id."},"definition_id":{"type":"string","nullable":true,"description":"Interview definition id."},"candidate_name":{"type":"string","nullable":true,"description":"Candidate name."},"candidate_email":{"type":"string","nullable":true,"description":"Candidate email."},"position_name":{"type":"string","nullable":true,"description":"Position / interview name."},"position_step":{"type":"string","nullable":true,"description":"Pipeline step."},"type":{"type":"string","nullable":true,"description":"Product type."},"emoji":{"type":"string","nullable":true,"description":"Emoji marker."},"external_id":{"type":"string","nullable":true,"description":"External identifier."},"mojito_language_code":{"type":"string","nullable":true,"description":"Platform language code."},"status":{"type":"string","nullable":true,"description":"Row status."},"coach_status":{"type":"string","nullable":true,"description":"Interview/coach status (started/completed/…)."},"decision_status":{"type":"string","nullable":true,"description":"Hiring decision (selected/rejected/…)."},"interview_started":{"type":"boolean","nullable":true,"description":"Whether the interview was started."},"is_multi_stage":{"type":"boolean","nullable":true,"description":"Whether multi-stage."},"is_test":{"type":"boolean","nullable":true,"description":"Whether a test result."},"recruiter_shortlist":{"type":"boolean","nullable":true,"description":"Whether recruiter-shortlisted."},"recruiter_risks":{"nullable":true,"description":"Detected recruiter risk flags (jsonb)."},"duration_ds":{"type":"number","nullable":true,"description":"Duration in deciseconds."},"score":{"type":"number","nullable":true,"description":"Overall score."},"score_simulation":{"type":"number","nullable":true,"description":"Simulated overall score."},"score_sentiment":{"type":"number","nullable":true,"description":"Sentiment sub-score."},"score_words_per_minute":{"type":"number","nullable":true,"description":"Speaking-pace sub-score."},"score_interview_ai":{"type":"number","nullable":true,"description":"AI interview sub-score."},"score_answer_ai":{"type":"number","nullable":true,"description":"AI answer sub-score."},"score_pronunciation":{"type":"number","nullable":true,"description":"Pronunciation sub-score."},"processing_status":{"type":"string","nullable":true,"description":"Processing status."},"processing_error":{"type":"string","nullable":true,"description":"Processing error, if any."},"kyc_processing_status":{"type":"string","nullable":true,"description":"KYC processing status."},"position_result_step_id":{"type":"string","nullable":true,"description":"Position result step id."},"created_at":{"type":"string","nullable":true,"description":"Creation timestamp (ISO 8601)."},"updated_at":{"type":"string","nullable":true,"description":"Last update timestamp (ISO 8601)."}},"required":["id"],"additionalProperties":{"nullable":true}},"description":"The merchant's interview results for this page."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"MerchantAnalyticsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","description":"Calendar day (YYYY-MM-DD).","example":"2026-01-15"},"event":{"type":"string","description":"Event type (e.g. interview, interview_invitation, interview_page_visit)."},"event_number":{"type":"number","description":"Count of this event on this day.","example":12}},"required":["day","event","event_number"],"additionalProperties":{"nullable":true}},"description":"Daily event counts for the requested range, ordered by day ascending."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"MerchantCandidateListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Candidate (profile_interview) id."},"profile_id":{"type":"string","nullable":true,"description":"Underlying profile id."},"merchant_id":{"type":"string","nullable":true,"description":"Owning merchant id."},"name":{"type":"string","nullable":true,"description":"Candidate name."},"email":{"type":"string","nullable":true,"description":"Candidate email."},"email_auth":{"type":"string","nullable":true,"description":"Auth email (login)."},"emoji":{"type":"string","nullable":true,"description":"Emoji marker."},"external_id":{"type":"string","nullable":true,"description":"External identifier."},"status":{"type":"string","nullable":true,"description":"Status (active/invited/deleted)."},"phone_number":{"type":"string","nullable":true,"description":"Phone number."},"linked_in":{"type":"string","nullable":true,"description":"LinkedIn URL."},"physical_address":{"type":"string","nullable":true,"description":"Physical address."},"mojito_language_code":{"type":"string","nullable":true,"description":"Platform language code."},"avatar_url":{"type":"string","nullable":true,"description":"Avatar image URL."},"avatar_local_path":{"type":"string","nullable":true,"description":"Avatar storage path."},"kyc_image_local_path":{"type":"string","nullable":true,"description":"KYC image storage path."},"kyc_processing_status":{"type":"string","nullable":true,"description":"KYC processing status."},"interview_count":{"type":"number","nullable":true,"description":"Number of interviews taken."},"pre_screening_count":{"type":"number","nullable":true,"description":"Number of pre-screenings taken."},"public_avatar_count":{"type":"number","nullable":true,"description":"Number of public-avatar conversations."},"interview_last":{"type":"string","nullable":true,"description":"Most recent interview timestamp (ISO 8601)."},"last_login_at":{"type":"string","nullable":true,"description":"Last login timestamp (ISO 8601)."},"created_at":{"type":"string","nullable":true,"description":"Creation timestamp (ISO 8601)."},"updated_at":{"type":"string","nullable":true,"description":"Last update timestamp (ISO 8601)."},"deleted_at":{"type":"string","nullable":true,"description":"Deletion timestamp (ISO 8601), if deleted."}},"required":["id"],"additionalProperties":{"nullable":true}},"description":"The merchant's candidates for this page."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"KnowledgeBaseDocumentUploadResponse":{"type":"object","properties":{"knowledge_base_id":{"type":"string","description":"Id of the created knowledge_base record."}},"required":["knowledge_base_id"]},"KnowledgeBaseDocumentUploadMultipart":{"type":"object","properties":{"knowledge_base_store_id":{"type":"string","minLength":1,"description":"The knowledge base store to add the document to.","example":"d9d6f121-1230-48fd-b3a7-8b5a1e8db052"},"name":{"type":"string","description":"Document name (with extension). Falls back to the uploaded file name for multipart."},"merchant_id":{"type":"string","description":"Override merchant id (admin / sub-merchant only)."},"file":{"type":"string","description":"The document file (binary).","format":"binary"}},"required":["knowledge_base_store_id","file"]},"KnowledgeBaseDocumentUploadJson":{"type":"object","properties":{"knowledge_base_store_id":{"type":"string","minLength":1,"description":"The knowledge base store to add the document to.","example":"d9d6f121-1230-48fd-b3a7-8b5a1e8db052"},"name":{"type":"string","description":"Document name (with extension). Falls back to the uploaded file name for multipart."},"merchant_id":{"type":"string","description":"Override merchant id (admin / sub-merchant only)."},"file":{"type":"string","minLength":1,"description":"The document file, base64-encoded."}},"required":["knowledge_base_store_id","file"]},"PreScreeningCreateResponse":{"type":"object","properties":{"created":{"type":"boolean","description":"True when a new pre-screening position was created."},"updated":{"type":"boolean","description":"True when an existing pre-screening position was updated."},"position_def_set_id":{"type":"string","nullable":true,"description":"The position_def_set id created or updated."},"interview_pre_screening_id":{"type":"string","nullable":true,"description":"The pre-screening definition id created or updated."}},"description":"On create returns `{ created: true, position_def_set_id, interview_pre_screening_id }`; on update returns `{ updated: true, position_def_set_id, interview_pre_screening_id }`."},"PreScreeningCreateRequest":{"type":"object","properties":{"update_position_def_set_id":{"type":"string","nullable":true,"description":"When set to an existing position id, the request updates that pre-screening position instead of creating a new one. When absent/empty, a new pre-screening position is created and the create-only mandatory fields are required.","example":"00000000-0000-0000-0000-000000000000"},"position_name":{"type":"string","nullable":true,"description":"Position name. Required when creating (no update_position_def_set_id).","example":"Customer Support Specialist"},"position_location":{"type":"string","nullable":true,"description":"Interview/position location. Required when creating.","example":"Remote"},"position_country_code":{"type":"string","nullable":true,"description":"ISO country code; stored upper-cased. Required when creating.","example":"US"},"position_description":{"type":"string","nullable":true,"description":"Short position description.","example":"Handle inbound customer requests."},"position_description_long":{"type":"string","nullable":true,"description":"Long position description."},"mojito_language_code":{"type":"string","nullable":true,"enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Mojito language code (one of the platform-languages.json codes). Required when creating.","example":"en"},"merchant_id":{"type":"string","nullable":true,"description":"Target merchant id. Only honored for admin or sub-merchant users; otherwise the caller's own merchant is used."},"type":{"type":"string","nullable":true,"enum":["resume","form","resume_with_form"],"description":"Pre-screening type. Defaults to \"resume\" on create."},"status":{"type":"string","nullable":true,"enum":["draft","active"],"description":"When \"active\", the pre-screening position is activated after create/update."},"assessment_rules":{"nullable":true,"description":"Assessment rules — an array of rule objects stored on the pre-screening definition.","example":[{"id":"form_nationality","type":"required","action":"mark_for_review"},{"id":"form_education","type":"required","action":"mark_for_review","education":"bachelors"},{"id":"resume_match","resume_score_accept":10,"resume_score_reject":0}]},"form_fields":{"nullable":true,"description":"Form fields definition (any JSON shape) stored on the pre-screening definition."},"candidate_expectations":{"type":"string","nullable":true,"description":"Candidate expectations text."},"visibility":{"type":"string","nullable":true,"description":"Position visibility. Defaults to \"merchant_invite\" on create."},"kombo_parameters":{"nullable":true,"description":"Kombo integration parameters (any JSON).","example":{"kombo_job_id":"7QzbCBaxX6fa4BMXBRuD7Lwm","kombo_stage_id":"CVjhZwxbtcer5P15gakmEhsM","kombo_sync_all_results":true,"kombo_selected_stage_id":null,"kombo_sync_all_results_stage_id":"9c5VZXrcMRmyr5vr1nvZWXSX"}},"interview_available_till":{"type":"string","nullable":true,"description":"Timestamp until which the interview is available."},"creation_parameters":{"nullable":true,"description":"Creation parameters, any JSON (create only)."}}},"PreScreeningResumeTextResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"decision_status":{"type":"string","description":"Applied decision status for the pre-screening step.","example":"recruiter_action"},"recommendation":{"type":"string","enum":["ai_accept","ai_reject","recruiter_action"],"description":"AI recommendation derived from the pre-screening status.","example":"recruiter_action"},"profile_interview_id":{"type":"string","description":"Candidate profile_interview id."},"interview_result_pre_screening_id":{"type":"string","description":"Inserted interview_result_pre_screening id."},"interview_file_id":{"type":"string","description":"Stored resume interview_file id."},"pre_screening_score":{"type":"number","nullable":true,"description":"AI match score."},"resume_ai_analysis":{"type":"string","nullable":true,"description":"AI resume analysis feedback."},"resume_ai_education":{"type":"string","nullable":true,"description":"AI-detected education level of the candidate."},"resume_ai_technical_experience":{"type":"number","nullable":true,"description":"AI-estimated years of relevant experience."},"resume_ai_is_switching_profession":{"type":"boolean","nullable":true,"description":"Whether the candidate is switching profession."},"processing_reason":{"type":"string","nullable":true,"description":"Reason the candidate failed screening, when applicable."}},"required":["success","decision_status","recommendation","profile_interview_id","interview_result_pre_screening_id","interview_file_id","pre_screening_score","resume_ai_analysis","resume_ai_education","resume_ai_technical_experience","resume_ai_is_switching_profession","processing_reason"],"description":"Result of the pre-screening analysis. When the candidate is not in the pre-screening candidate_action state, a `{ decision_status, message }` object is returned instead."},"PreScreeningNotApplicable":{"type":"object","properties":{"decision_status":{"type":"string","example":"unknown"},"message":{"type":"string"}},"required":["decision_status","message"]},"PreScreeningResumeTextRequest":{"type":"object","properties":{"position_id":{"type":"string","minLength":1,"description":"Position (position_def_set) id the candidate is being screened against.","example":"00000000-0000-0000-0000-000000000000"},"candidate_name":{"type":"string","minLength":1,"description":"Candidate full name.","example":"Jane Doe"},"candidate_email":{"type":"string","minLength":1,"description":"Candidate email (normalised to trimmed lowercase).","example":"jane.doe@example.com"},"candidate_country_code":{"type":"string","minLength":1,"description":"Candidate country code, used as default residency/nationality.","example":"US"},"candidate_resume":{"type":"string","minLength":1,"description":"Plaintext candidate resume.","example":"Experienced software engineer with 8 years ..."},"candidate_external_id":{"type":"string","description":"Optional external identifier stored on the candidate profile.","example":"ATS-12345"},"candidate_linkedin_url":{"type":"string","description":"Optional LinkedIn profile URL stored on the candidate profile.","example":"https://www.linkedin.com/in/jane-doe"},"form":{"type":"object","properties":{"education":{"type":"string","description":"Highest education level key.","example":"masters_degree"},"languages":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Language code.","example":"en"},"level":{"type":"string","description":"Proficiency level key.","example":"c2"}}},"description":"Candidate language proficiencies."},"residency":{"type":"string","description":"Country code of residency. Defaults to candidate_country_code when omitted.","example":"US"},"nationality":{"type":"string","description":"Country code of nationality. Defaults to candidate_country_code when omitted.","example":"US"},"visa":{"type":"string","description":"Visa status key.","example":"has_visa"},"age":{"type":"integer","description":"Candidate age in years.","example":30},"gender":{"type":"string","description":"Candidate gender (free text; standard values: male, female).","example":"male"}},"additionalProperties":{"nullable":true},"description":"Optional structured pre-screening form used by the assessment rules. Custom fields (defined via form_fields) are also accepted."}},"required":["position_id","candidate_name","candidate_email","candidate_country_code","candidate_resume"]},"PreScreeningResumeBinarySuccess":{"type":"object","properties":{"success":{"type":"boolean"},"decision_status":{"type":"string"},"recommendation":{"type":"string","nullable":true},"profile_interview_id":{"type":"string"},"interview_result_pre_screening_id":{"type":"string"},"interview_file_id":{"type":"string"},"pre_screening_score":{"type":"number","nullable":true},"resume_ai_analysis":{"type":"string","nullable":true},"resume_ai_education":{"type":"string","nullable":true},"resume_ai_technical_experience":{"type":"number","nullable":true},"resume_ai_is_switching_profession":{"type":"boolean","nullable":true},"processing_reason":{"type":"string","nullable":true}},"required":["success","decision_status","recommendation","profile_interview_id","interview_result_pre_screening_id","interview_file_id","pre_screening_score","resume_ai_analysis","resume_ai_education","resume_ai_technical_experience","resume_ai_is_switching_profession","processing_reason"]},"PreScreeningResumeBinaryEarlyExit":{"type":"object","properties":{"decision_status":{"type":"string"},"message":{"type":"string"}},"required":["decision_status","message"]},"PreScreeningResumeBinaryResponse":{"anyOf":[{"$ref":"#/components/schemas/PreScreeningResumeBinarySuccess"},{"$ref":"#/components/schemas/PreScreeningResumeBinaryEarlyExit"}],"description":"Either the completed pre-screening result, or an early-exit status message when the candidate is not in the pre-screening candidate_action state."},"PreScreeningResumeBinaryRequest":{"type":"object","properties":{"position_id":{"type":"string","minLength":1,"description":"The position the candidate is being pre-screened against."},"candidate_name":{"type":"string","minLength":1,"description":"Full name of the candidate."},"candidate_email":{"type":"string","minLength":1,"description":"Candidate email (normalized to lowercase, trimmed)."},"candidate_country_code":{"type":"string","minLength":1,"description":"ISO country code used as residency/nationality fallback."},"candidate_external_id":{"type":"string","description":"Optional external identifier for the candidate."},"candidate_linkedin_url":{"type":"string","description":"Optional candidate LinkedIn profile URL."},"file":{"type":"string","description":"Resume file (pdf, doc, docx, txt, etc.)","format":"binary"},"form":{"type":"string","description":"Optional JSON string with education/languages/residency/nationality/visa/age/gender."}},"required":["position_id","candidate_name","candidate_email","candidate_country_code","file"]},"InviteUsersResponse":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"interview_id":{"type":"string","nullable":true},"result":{"type":"string","description":"Outcome, e.g. 'Invited', 'Activated', 'SubMerchantAdded', 'Skipped', or 'Error: <message>'."},"profile_id":{"type":"string","nullable":true},"profile_interview_id":{"type":"string","nullable":true}},"required":["email"],"additionalProperties":{"nullable":true}},"description":"The input users array, each augmented with the invitation result fields."},"InviteUsersRequest":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","nullable":true,"description":"Email address of the person to invite. Validated per item; an invalid/missing value produces a per-item error result, not a request-level 422.","example":"hello@google.com"},"name":{"type":"string","nullable":true,"description":"Display name for the invited profile.","example":"mr. Brown"},"type":{"type":"string","nullable":true,"description":"Invite type — selects which kind of account is created. Defaults to 'user'. Admin / merchant-team roles (manage the recruiting dashboard): `merchant_owner`, `merchant`, `merchant_selection`. Coaching-portal users: `user`, `mentor`. Interview candidate: `candidate` (requires `interview_id`). An invalid value yields a per-item error result rather than a request-level failure.","example":"merchant"},"interview_id":{"type":"string","nullable":true,"format":"uuid","description":"Interview/position id. Mandatory when type is 'candidate'.","example":"d1c00b60-7e75-4292-9190-7037b95b349a"}},"additionalProperties":{"nullable":true}},"description":"List of users to invite."},"force_invite":{"type":"boolean","nullable":true,"description":"When true, re-sends the invite email for still-pending (invited) profiles that did not otherwise produce a result.","example":false},"merchant_id":{"type":"string","nullable":true,"format":"uuid","description":"Target merchant id. Required when calling with a service-role key. For admins / sub-merchant users it overrides the JWT merchant.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"mojito_language_code":{"type":"string","nullable":true,"enum":["ar","bg","zh","hr","cs","da","nl","en","fil","fi","fr","de","el","hi","hu","id","it","ja","ko","ms","no","pl","pt","br","ro","ru","sk","es","sv","ta","th","tr","uk","vi"],"description":"Language code applied to created profiles (one of the platform-languages.json codes). Defaults to 'en' when omitted.","example":"en"},"message_from_recruiter":{"type":"string","nullable":true,"description":"Optional custom message included in the invitation email."}},"required":["users"]},"MerchantSubMerchantListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Sub-merchant id."},"name":{"type":"string","nullable":true,"description":"Sub-merchant name."},"status":{"type":"string","nullable":true,"description":"Status."},"contact_person":{"type":"string","nullable":true,"description":"Primary contact name."},"contact_email":{"type":"string","nullable":true,"description":"Primary contact email."},"billing_country":{"type":"string","nullable":true,"description":"Billing country."},"business_type":{"type":"string","nullable":true,"description":"Business type."},"image_logo_url":{"type":"string","nullable":true,"description":"Logo image URL."},"frontend_domain":{"type":"string","nullable":true,"description":"Consumer frontend domain."},"interview_frontend_domain":{"type":"string","nullable":true,"description":"Interview frontend domain."},"register_domain":{"type":"string","nullable":true,"description":"Registration domain."},"info_notes":{"type":"string","nullable":true,"description":"Internal notes."},"merchant_features":{"nullable":true,"description":"Enabled feature flags (jsonb)."},"interview_subscription_status":{"type":"string","nullable":true,"description":"Interview subscription status."},"interview_subscription_type":{"type":"string","nullable":true,"description":"Interview subscription type."},"stripe_interview_subscription_start":{"type":"string","nullable":true,"description":"Subscription start (ISO 8601)."},"consumer_webanalytics":{"type":"string","nullable":true,"description":"Consumer web-analytics id."},"interview_webanalytics":{"type":"string","nullable":true,"description":"Interview web-analytics id."},"admin_profiles":{"nullable":true,"description":"Admin profiles linked to this sub-merchant (jsonb)."},"users":{"nullable":true,"description":"Users linked to this sub-merchant (jsonb)."},"interview_count":{"type":"number","nullable":true,"description":"Total interviews run."},"interview_latest":{"type":"string","nullable":true,"description":"Most recent interview timestamp (ISO 8601)."},"credits_used_30d":{"type":"number","nullable":true,"description":"Credits used in the last 30 days."},"credits_used_total":{"type":"number","nullable":true,"description":"Total credits used."},"created_at":{"type":"string","nullable":true,"description":"Creation timestamp (ISO 8601)."}},"required":["id"],"additionalProperties":{"nullable":true}},"description":"The sub-merchants the caller administers for this page."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"MerchantAvatarListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Avatar template id."},"merchant_id":{"type":"string","nullable":true,"description":"Owning merchant id."},"name":{"type":"string","nullable":true,"description":"Template name."},"type":{"type":"string","nullable":true,"description":"Avatar template type."},"status":{"type":"string","nullable":true,"description":"Status (active/draft/archived/deleted)."},"visibility":{"type":"string","nullable":true,"description":"Visibility (public/merchant_…)."},"mojito_language_code":{"type":"string","nullable":true,"description":"Platform language code."},"video_voice_language_name":{"type":"string","nullable":true,"description":"Voice language display name."},"media_url":{"type":"string","nullable":true,"description":"Avatar media URL."},"background_url":{"type":"string","nullable":true,"description":"Background image URL."},"background_blur":{"type":"boolean","nullable":true,"description":"Whether the background is blurred."},"video_background_remove":{"type":"boolean","nullable":true,"description":"Whether the video background is removed."},"video_avatar_image_url":{"type":"string","nullable":true,"description":"Avatar still-image URL."},"video_avatar_aspect_ratio":{"type":"string","nullable":true,"description":"Avatar aspect ratio."},"created_at":{"type":"string","nullable":true,"description":"Creation timestamp (ISO 8601)."},"updated_at":{"type":"string","nullable":true,"description":"Last update timestamp (ISO 8601)."}},"required":["id"],"additionalProperties":{"nullable":true}},"description":"The merchant's avatar templates for this page, newest-updated first."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}},"parameters":{}},"paths":{"/job-interview-create":{"post":{"tags":["Interviews"],"summary":"Create a new interview","description":"Creates a new interview / coaching / assessment definition, generates its description, questions and candidate expectations via AI, and provisions default steps. Optionally provisions an embed key.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateRequest"}}}},"responses":{"200":{"description":"Interview created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error (missing required field, invalid enum value, out-of-range number, or unresolved template/language/knowledge-base id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures and unhandled exceptions).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-create-from-array":{"post":{"tags":["Interviews"],"summary":"Create an interview from an array of questions","description":"Creates a new interview definition set from a caller-provided array of questions, builds its default and generated steps, optionally activates it, and optionally creates an embed key.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateFromArrayRequest"}}}},"responses":{"200":{"description":"Interview created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateFromArrayResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures and unresolved template/knowledge-base/language ids).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-create-for-candidate-with-token":{"post":{"tags":["Interviews"],"summary":"Create an interview for a candidate and return an access token URL","description":"Creates (or resolves an existing) position and interview for a merchant, enrols the candidate, runs pre-screening, and returns a tokenised interview URL. Position fields are required only when position_def_set_id is not provided.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateForCandidateWithTokenRequest"}}}},"responses":{"200":{"description":"Candidate enrolled. Decision status, ids, and a tokenised interview URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewCreateForCandidateWithTokenResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested position_def_set_id could not be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error (missing/invalid fields, unresolved merchant/language/template).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures and unhandled exceptions).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-get":{"get":{"tags":["Interviews"],"summary":"Get interview definition","description":"Retrieves the interview definition for a given interview-definition id or position id. Returns the compiled `calc_definition_json` plus basic metadata. Access is subject to the caller's row-level security.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"format":"uuid","description":"Identifier of either an interview definition (single-stage) or a position definition (multi-stage). The function resolves whichever matches.","example":"00000000-0000-0000-0000-000000000000"},"required":true,"name":"position_id","in":"query"}],"responses":{"200":{"description":"The resolved interview definition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewGetResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No interview or position found for the given id (or hidden by row-level security).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-set-state":{"post":{"tags":["Interviews"],"summary":"Set interview state","description":"Changes the lifecycle status of an interview or position (draft, active, archived, preparing, completed, deleted) and/or manages its embed key. Provide at least one of `status` or `is_embedded`.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewSetStateRequest"}}}},"responses":{"200":{"description":"State updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewSetStateResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures and unresolved position/interview ids).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-token":{"post":{"tags":["Interviews"],"summary":"Generate a signed interview URL","description":"Generates a public, token-signed URL for an existing interview, profile, or result. The required id fields depend on `type`.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewTokenRequest"}}}},"responses":{"200":{"description":"The signed URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewTokenResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error (invalid type, missing conditional fields, unauthenticated, or interview not found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-register-users":{"post":{"tags":["Interviews"],"summary":"Register users for an interview","description":"Registers (or updates) one or more candidate profiles for an interview and returns a one-time interview URL for each. Accepts a Supabase user JWT (merchant/admin) or the service key (merchant_id then required).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewRegisterUsersRequest"}}}},"responses":{"200":{"description":"Per-user registration results.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewRegisterUsersResponse"}}}},"401":{"description":"Unauthenticated user (user token with no resolvable user).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error (missing required fields, missing merchant_id with service key, or interview not found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-interview-list":{"get":{"tags":["Interviews"],"summary":"List interview definitions","description":"Paginated list of a merchant's interview definitions (the admin-portal interview list), scoped to the merchant from the JWT or the optional merchant_id override. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","enum":["interview","coaching","assessment","public_avatar","persona"],"default":"interview","description":"Product type of interviews to list.","example":"interview"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["draft","active","archived","deleted","preparing","completed"],"description":"Filter by lifecycle status. Omit to include all statuses.","example":"active"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"Include interviews shared publicly across merchants (coaching/avatars).","example":"false"},"required":false,"name":"show_public","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"Include demo/sample interviews.","example":"false"},"required":false,"name":"show_demo","in":"query"},{"schema":{"type":"string","description":"Case-insensitive search on the interview name."},"required":false,"name":"filter_text","in":"query"},{"schema":{"type":"string","description":"Filter by the interview emoji marker."},"required":false,"name":"filter_emoji","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of interview definitions with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantInterviewListResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-details":{"get":{"tags":["Results"],"summary":"Get interview result details with transcript","description":"Returns an interview result with its full transcript and AI assessment. Optionally attaches signed recording URLs.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"format":"uuid","description":"The interview result to fetch the transcript and details for.","example":"93c98d21-e04d-4a84-9afa-ed154cf73636"},"required":true,"name":"interview_result_id","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"When true, includes short-lived signed recording URLs for the session, the video introduction, and each transcript answer.","example":"false"},"required":false,"name":"get_signed_recordings","in":"query"}],"responses":{"200":{"description":"The interview result and transcript.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewDetailsResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No interview result exists for the given interview_result_id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-pdf":{"post":{"tags":["Results"],"summary":"Generate an interview report","description":"Generates an interview result report as a PDF (returns a signed URL), raw HTML, or structured JSON. Provide either `interview_result_id` for a single result or `interview_result_ids` for a combined multi-result report.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewPdfRequest"}}}},"responses":{"200":{"description":"The generated report. The body is one of three shapes, selected by the request `export_type`: `pdf` → `{ pdf_export_url, pdf_export_valid_until }`; `html` → `{ html_export }`; `json` → `{ json_export }`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobInterviewPdfResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-result-request-another-attempt":{"post":{"tags":["Results"],"summary":"Request another interview attempt","description":"Marks a submitted (active + completed) interview result as unsuccessful so the candidate can retake it. Resets the result to draft and clears the recruiter decision.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestAnotherAttemptRequest"}}}},"responses":{"200":{"description":"The result was reset for another attempt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestAnotherAttemptResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error: missing/invalid id, result not found, or the result is not in an active+submitted state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-result-list":{"get":{"tags":["Results"],"summary":"List interview results","description":"Paginated list of a merchant's interview results (the admin-portal results list), scoped to the merchant from the JWT or the optional merchant_id override. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","enum":["interview","coaching","assessment","public_avatar","persona"],"default":"interview","description":"Product type of results to list.","example":"interview"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["decided-rejected","undecided","shortlist","decided-selected","completed","incomplete","archived-interview","public_avatar","archived-public_avatar",""],"description":"Filter by decision/completion state. Omit (or empty) to include all.","example":"undecided"},"required":false,"name":"tab","in":"query"},{"schema":{"type":"string","enum":["pre-screening","interview"],"description":"Filter by pipeline step (pre-screening vs interview). Omit for both.","example":"interview"},"required":false,"name":"step","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to a single interview definition id."},"required":false,"name":"interview_id","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to a single candidate (profile_interview) id."},"required":false,"name":"profile_interview_id","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of recruiter-risk keys to filter by (matches any)."},"required":false,"name":"risks","in":"query"},{"schema":{"type":"string","enum":["score","created_at_newest","created_at_oldest","updated_at_newest"],"default":"created_at_newest","description":"Sort order of the result set.","example":"created_at_newest"},"required":false,"name":"order_by","in":"query"},{"schema":{"type":"string","description":"Case-insensitive search on candidate name or email."},"required":false,"name":"filter_text","in":"query"},{"schema":{"type":"string","description":"Filter by the candidate emoji marker."},"required":false,"name":"filter_emoji","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of interview results with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantResultListResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-analytics":{"get":{"tags":["Results"],"summary":"Get daily event analytics","description":"Daily event-count time-series for a merchant over a date range (the admin-portal analytics events graph), scoped to the merchant from the JWT or the optional merchant_id override. Optionally drilled to a single interview. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Start of the date range (inclusive), YYYY-MM-DD.","example":"2026-01-01"},"required":true,"name":"date_from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"End of the date range (inclusive), YYYY-MM-DD.","example":"2026-01-01"},"required":true,"name":"date_to","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Optional interview definition id to drill the event counts down to a single interview."},"required":false,"name":"interview_id","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of daily event counts with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantAnalyticsResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-candidate-list":{"get":{"tags":["Candidates"],"summary":"List candidates","description":"Paginated list of a merchant's candidates (the admin-portal candidates list), scoped to the merchant from the JWT or the optional merchant_id override. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","enum":["interview","pre-screening","no-action","leads",""],"description":"Filter candidates by recent activity. Omit (or empty) to include all.","example":"interview"},"required":false,"name":"tab","in":"query"},{"schema":{"type":"string","enum":["invited","registered"],"description":"Filter by how the candidate entered: invited or self-registered. Omit for both.","example":"registered"},"required":false,"name":"source","in":"query"},{"schema":{"type":"string","enum":["name_accending","name_decending","created_at_newest","created_at_oldest"],"default":"created_at_newest","description":"Sort order of the result set.","example":"created_at_newest"},"required":false,"name":"order_by","in":"query"},{"schema":{"type":"string","description":"Case-insensitive search on candidate name or email."},"required":false,"name":"filter_text","in":"query"},{"schema":{"type":"string","description":"Filter by the candidate emoji marker."},"required":false,"name":"filter_emoji","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of candidates with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantCandidateListResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/knowledge-base-document-upload":{"post":{"tags":["Knowledge base"],"summary":"Upload a knowledge base document","description":"Uploads a document to a knowledge base store and queues it for processing. Accepts the file either as multipart/form-data (binary `file`) or as application/json (base64 `file`).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/KnowledgeBaseDocumentUploadMultipart"}},"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeBaseDocumentUploadJson"}}}},"responses":{"200":{"description":"The document was uploaded and queued for processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeBaseDocumentUploadResponse"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures and a missing/invalid file or store).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pre-screening-create":{"post":{"tags":["Resume & Form verification"],"summary":"Create or update a pre-screening position","description":"Creates a new pre-screening position (and optionally activates it) or, when update_position_def_set_id is provided, updates an existing pre-screening position. Only merchant_owner, merchant, or admin users may call this.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreScreeningCreateRequest"}}}},"responses":{"200":{"description":"The pre-screening position was created or updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreScreeningCreateResponse"}}}},"401":{"description":"Missing, expired or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Pre-screening step not found for the given position (update path).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error or unresolved merchant_id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error (includes authorization failures).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-pre-screening-api-resume-text":{"post":{"tags":["Resume & Form verification"],"summary":"Run pre-screening on a plaintext resume","description":"Stores a plaintext candidate resume, runs AI pre-screening against the position definition, records the result and returns the AI recommendation and analysis. If the candidate is not in the pre-screening candidate_action state, an early `{ decision_status, message }` object is returned with HTTP 200.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreScreeningResumeTextRequest"}}}},"responses":{"200":{"description":"Pre-screening completed, or an early `{ decision_status, message }` result when the candidate is not in the pre-screening candidate_action state.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PreScreeningResumeTextResponse"},{"$ref":"#/components/schemas/PreScreeningNotApplicable"}]}}}},"401":{"description":"Missing or invalid authentication.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated user is not a merchant user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Position not found or does not belong to this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error (missing required field or unresolved merchant_id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/job-interview-pre-screening-api-resume-binary":{"post":{"tags":["Resume & Form verification"],"summary":"Pre-screen a candidate from a binary resume upload","description":"Accepts a multipart/form-data upload with candidate details and a binary resume file, converts the resume to text, runs AI pre-screening against the position, stores the result, and returns the decision.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/PreScreeningResumeBinaryRequest"}}}},"responses":{"200":{"description":"Pre-screening result, or an early-exit status message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreScreeningResumeBinaryResponse"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: only merchant users can access this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Position not found or does not belong to this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invite-users":{"post":{"tags":["Admin"],"summary":"Invite admin / merchant-team or coaching users","description":"Invites people to a merchant account and emails each one an invitation. Use it to add **admin / merchant-team users** who manage the recruiting dashboard (`merchant_owner`, `merchant`, `merchant_selection`), **coaching-portal users** (`user`, `mentor`), or **interview candidates** (`candidate`). Candidate invites require an `interview_id` and are gated by the merchant's available interview credits; admin and coaching invites are not. Each user in the array is processed independently and returned with an individual result, so one failure does not block the rest. Callable with a merchant JWT (merchant_owner/merchant/admin) or a service-role key (requires merchant_id).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteUsersRequest"}}}},"responses":{"200":{"description":"The users array with per-item invitation results.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteUsersResponse"}}}},"403":{"description":"The caller does not have access to the requested merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error, missing merchant_id for service role, or unauthenticated user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-sub-merchant-list":{"get":{"tags":["Admin"],"summary":"List sub-merchants","description":"Paginated list of the sub-merchants the caller administers (the admin-portal sub-merchants list). Visibility is enforced by row-level security. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","enum":["name","created_at_newest","created_at_oldest"],"default":"created_at_newest","description":"Sort order of the result set.","example":"created_at_newest"},"required":false,"name":"order_by","in":"query"},{"schema":{"type":"string","description":"Case-insensitive search on the sub-merchant name."},"required":false,"name":"filter_text","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of sub-merchants with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantSubMerchantListResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read sub-merchants.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/merchant-avatar-list":{"get":{"tags":["Admin"],"summary":"List avatar templates","description":"Paginated list of a merchant's avatar templates (the admin-portal avatars list), scoped to the merchant from the JWT or the optional merchant_id override. Capped at 1000 records per page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Optional merchant to scope the results to. Honoured only when the caller is an admin or a sub-merchant operator; otherwise the merchant from the JWT is always used.","example":"28106cba-1c27-4e53-b149-32113e5e8e31"},"required":false,"name":"merchant_id","in":"query"},{"schema":{"type":"string","enum":["interactive_heygen","interactive_elevenlabs","offline_heygen","offline_elai","offline_synthesia"],"description":"Filter by avatar template type. Omit for all.","example":"interactive_heygen"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["active","draft","archived","deleted"],"description":"Filter by status. Omit for all except archived (see include_archived).","example":"active"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","description":"Filter by platform language code."},"required":false,"name":"mojito_language_code","in":"query"},{"schema":{"type":"string","description":"Case-insensitive search on template name or voice language name."},"required":false,"name":"filter_text","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"Include archived templates (excluded by default).","example":"false"},"required":false,"name":"include_archived","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"Also include public templates shared across merchants, in addition to this merchant's own.","example":"false"},"required":false,"name":"include_public","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of records to return (1–1000).","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip from the start of the result set.","example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of avatar templates with pagination metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantAvatarListResponse"}}}},"401":{"description":"Missing or invalid access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller is not permitted to read this merchant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}