> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Interview

> Creates an interview for a candidate using an existing or inline candidate/agent/job, scoped to the API key's company. Respects company billing limits and subscription plans. Set isTest=true to create a test interview that immediately completes without consuming billing minutes.

Creates a new AI-powered interview session for a candidate. This endpoint supports both existing candidates/agents and inline resource creation, making it flexible for various integration scenarios.

## Overview

The create interview endpoint allows you to schedule AI-powered interviews with candidates. You can use existing candidate and agent IDs, or create them on-the-fly using inline definitions. Interviews can be scheduled for a future time or started immediately.

## Use Cases

* **Scheduled Interviews**: Schedule interviews for a specific date and time
* **Immediate Interviews**: Start interviews right away for quick screening
* **Inline Resources**: Create interviews without pre-creating candidates or agents
* **Bulk Interview Scheduling**: Automate interview scheduling for multiple candidates

## Inline Candidate, Agent, and Job Support

You can create interviews with candidates, agents, and jobs that don't exist yet by providing inline resource objects. This enables streamlined interview scheduling without pre-creating resources in your system.

### Inline Candidate with Job Association

```javascript theme={null}
{
  "candidate": {
    "jobId": "job-uuid",
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "phoneNumber": "+1234567890",
    "gdprExpiryDate": "2026-11-16",
    "workHistory": [
      {
        "companyName": "Tech Corp",
        "candidatePosition": "Software Engineer",
        "referenceName": "Jane Smith",
        "referencePhone": "+1234567890",
        "startDate": "2020-01-01",
        "endDate": "2022-12-31"
      }
    ]
  },
  "agentId": "existing-agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}

```

### Inline Candidate with Inline Job

Create both the candidate and job inline for a completely self-contained interview creation:

```javascript theme={null}
{
  "candidate": {
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "phoneNumber": "+1234567890",
    "gdprExpiryDate": "2026-11-16"
  },
  "job": {
    "jobTitle": "Senior Backend Engineer",
    "jobDescription": "We are looking for a senior engineer...",
    "requiredSkills": ["TypeScript", "NestJS", "PostgreSQL"],
    "niceToHaveSkills": ["Redis", "AWS"],
    "languages": ["EN"],
    "experience": "SENIOR",
    "contractType": "FULL_TIME"
  },
  "agentId": "existing-agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Info>
  **Complete Inline Workflow**: When using `candidate` with
  `job`: - A new **Job** entity is created in your company - A new
  **Candidate** entity is created and automatically associated with the new job

  * The **Interview** is linked to both the new candidate and job - All
    resources become permanent entities in your system - This is the most
    streamlined way to schedule interviews without any pre-existing resources
</Info>

### Inline Candidate without Job Association

```javascript theme={null}
{
  "candidate": {
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "phoneNumber": "+1234567890",
    "gdprExpiryDate": "2026-11-16"
  },
  "agentId": "existing-agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Info>
  **Job Specification Options**: You can specify the job in several ways: -
  **Create inline**: Use `job` at the DTO level to create a new job -
  **Reference existing**: Use `jobId` at the DTO level to link to an existing
  job - **Within inline candidate**: Use `jobId` inside `candidate`
  for a more compact syntax when creating both candidate and job association -
  **No job**: Omit all job fields to create a candidate in your talent pool
  without job association (can be assigned later via the [update candidate
  endpoint](/api-reference/candidates/update-candidate)) **Priority**: When
  multiple job sources are provided, `job` takes precedence over
  DTO-level `jobId`, which takes precedence over `candidate.jobId`.
  **XOR Validation**: You cannot combine `candidate.jobId` with DTO-level
  job fields (`jobId` or `job`) as this would be ambiguous. Choose one
  method per request.
</Info>

## Generic Focus and Jobless Interviews

<Warning>
  **GENERIC Focus Requirement**: When using an agent with `focus: "GENERIC"`, the candidate must NOT have any job assignments. This is required for jobless interviews.
</Warning>

Generic focus agents are designed for interviews where candidates don't need to be assigned to a specific job. This is useful for:

* **Talent Pool Building**: Interviewing candidates for future opportunities without a specific role
* **General Outreach**: Engaging with candidates in your database who aren't currently assigned to jobs
* **Pre-screening**: Conducting initial conversations before matching candidates to specific positions

### Creating a Jobless Interview with GENERIC Focus

```javascript theme={null}
{
  "candidate": {
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "phoneNumber": "+1234567890",
    "gdprExpiryDate": "2026-11-16"
    // No jobId - candidate has no job assignments
  },
  "agentId": "generic-agent-uuid", // Agent with focus: "GENERIC"
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Info>
  **Validation**: The API will return a `400 Bad Request` error if:

  * You use a GENERIC focus agent with a candidate that has job assignments
  * You try to create a jobless interview (no job specified) with a non-GENERIC agent

  For more details on Generic interview analysis structure, see the [Interviews Resource Guide](/guides/resources/interviews#generic).
</Info>

### Existing Candidate with Inline Job

You can also define the job inline using `job` when you already have a candidate but don't want to create a separate job resource first.

```javascript theme={null}
{
  "candidateId": "candidate-uuid",
  "job": {
    "jobTitle": "Senior Backend Engineer",
    "jobDescription": "We are looking for a senior engineer...",
    "jobUrl": "https://company.com/jobs/123",
    "benefits": "Health insurance, remote work",
    "requiredSkills": ["TypeScript", "NestJS", "PostgreSQL"],
    "niceToHaveSkills": ["Redis", "AWS"],
    "languages": ["EN"],
    "languageRequirements": [
      { "language": "EN", "proficiency": "C1" }
    ],
    "education": ["BACHELORS"],
    "experience": "SENIOR",
    "otherRequirements": "Comfortable with async communication",
    "contractType": "FULL_TIME",
    "location": {
      "workMode": "REMOTE",
      "street": "Main Street 1",
      "city": "Bratislava",
      "postalCode": "81101",
      "countryCode": "SK"
    },
    "salary": {
      "min": 4000,
      "max": 5500,
      "currency": "EUR",
      "period": "MONTHLY"
    },
    "humanRecruiter": "John Doe",
    "metadata": {
      "externalJobId": "JOB-12345",
      "department": "Engineering"
    }
  },
  "agentId": "existing-agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Info>
  **Inline Job Behavior**: - When you provide `job` together with an
  existing `candidateId`, the API: - Creates a full **Job** entity in your
  company using the inline fields. - Automatically associates the candidate
  with the new job if they weren't already linked. - Links the interview to this
  newly created job. - `jobId` and `job` are **mutually exclusive (XOR)**: -
  Use **either** `jobId` (existing job) **or** `job` (inline job
  definition), but not both.
</Info>

## Billing and Limits

<Warning>
  Creating interviews consumes interview minutes from your company's billing
  plan. Ensure you have sufficient minutes available before scheduling bulk
  interviews. The API will return a `403 Forbidden` error if billing limits are
  exceeded.

  **Exception:** Test interviews (created with `isTest: true`) do not consume billing minutes and bypass all billing checks.
</Warning>

## Scheduling Options

### Immediate Interview

Omit `scheduleTime` to start the interview immediately:

```javascript theme={null}
{
  "candidateId": "candidate-uuid",
  "agentId": "agent-uuid"
}
```

### Scheduled Interview

Provide a future `scheduleTime` timestamp (max 30 days in the future):

```javascript theme={null}
{
  "candidateId": "candidate-uuid",
  "agentId": "agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Info>
  **Note**: When using existing candidates, ensure they already exist in your
  system. For inline candidates, all required fields (firstName, lastName,
  email or phoneNumber, gdprExpiryDate) must be provided.
</Info>

## Job Selection for Existing Candidates

When using an existing `candidateId`, you can optionally specify a `jobId` to indicate which job the interview is for. This is especially important when a candidate is associated with multiple jobs.

### Candidate with Single Job

If the candidate has only one job (or no jobs), the `jobId` field is optional. The system will automatically use the candidate's first job if available:

```javascript theme={null}
{
  "candidateId": "candidate-uuid",
  "agentId": "agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
  // jobId is optional - system uses candidate's first job
}
```

### Candidate with Multiple Jobs

When a candidate is associated with multiple jobs, you **must** specify the `jobId` to indicate which job the interview is for:

```javascript theme={null}
{
  "candidateId": "candidate-uuid",
  "jobId": "job-uuid",  // Required when candidate has multiple jobs
  "agentId": "agent-uuid",
  "scheduleTime": "2024-01-20T14:00:00Z"
}
```

<Warning>
  **Multiple Job Assignments**: If a candidate has multiple job assignments and
  you don't provide `jobId`, the API will return a `400 Bad Request` error with
  the message "Job ID must be provided when candidate has multiple job
  assignments".
</Warning>

<Info>
  **Job Association**: The `jobId` you provide must belong to the same company as your API key. If the candidate is not already assigned to this job, they will be automatically assigned to it when the interview is created.
</Info>

<Info>
  **Job Selection Rules**: - `jobId` and `job` are XOR (mutually exclusive): - If you
  provide `jobId`, you must omit `job`. - If you provide
  `job`, you must omit `jobId`. - When `job` is used: - A new
  job is created for your company. - That job is used as the interview's
  `jobId`. - The candidate is associated with that job automatically before the
  interview is created.
</Info>

## Company Isolation

All resources (candidate, agent, job) must belong to the same company as your API key. The API automatically validates company ownership and returns `403 Forbidden` if resources belong to different companies.

## Complete Workflow Examples

### Scenario 1: Interview with Job Association

```javascript theme={null}
// 1. Create a job (if not exists)
const job = await createJob({
  title: "Senior Software Engineer",
  status: "OPEN",
});

// 2. Create interview with inline candidate linked to job
const interview = await createInterview({
  candidate: {
    jobId: job.id,
    firstName: "Jane",
    lastName: "Doe",
    email: "jane@example.com",
    phoneNumber: "+1234567890",
    gdprExpiryDate: "2026-11-16",
  },
  agentId: "agent-uuid",
  scheduleTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // Tomorrow
});

// 3. Monitor interview status
const status = await getInterview(interview.id);
console.log(`Interview status: ${status.status}`);
```

### Scenario 2: Interview without Job Association (Talent Pool)

```javascript theme={null}
// 1. Create interview for candidate in talent pool (no job specified)
const interview = await createInterview({
  candidate: {
    firstName: "John",
    lastName: "Smith",
    email: "john@example.com",
    phoneNumber: "+1234567890",
    gdprExpiryDate: "2026-11-16",
  },
  agentId: "agent-uuid",
  scheduleTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
});

// 2. Later, assign candidate to specific job(s) if needed
const candidateId = interview.candidateId;
await updateCandidate(candidateId, {
  jobIds: ["job-uuid-1", "job-uuid-2"],
});
```

### Scenario 3: Interview for Candidate with Multiple Jobs

```javascript theme={null}
// 1. Candidate is associated with multiple jobs
const candidate = await getCandidate("candidate-uuid");
// candidate.jobIds = ["job-1-uuid", "job-2-uuid", "job-3-uuid"]

// 2. Create interview for a specific job (jobId is required)
const interview = await createInterview({
  candidateId: "candidate-uuid",
  jobId: "job-2-uuid", // Must specify which job
  agentId: "agent-uuid",
  scheduleTime: "2024-01-20T14:00:00Z",
});

// 3. Interview is now associated with job-2-uuid
console.log(`Interview created for job: ${interview.jobId}`);
```

### Scenario 4: Existing Candidate with Inline Job

```javascript theme={null}
// 1. Candidate already exists in your system
const candidateId = "candidate-uuid";

// 2. Create interview and define job inline
const interview = await createInterview({
  candidateId,
  job: {
    jobTitle: "Senior Backend Engineer",
    jobDescription: "We are looking for a senior engineer...",
    requiredSkills: ["TypeScript", "NestJS", "PostgreSQL"],
    niceToHaveSkills: ["Redis", "AWS"],
    languages: ["EN"],
    experience: "SENIOR",
    contractType: "FULL_TIME",
    location: { workMode: "REMOTE", countryCode: "SK" },
    metadata: { externalJobId: "JOB-12345" },
  },
  agentId: "agent-uuid",
  scheduleTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
});

console.log(`Interview jobId: ${interview.jobId}`);
```

<Info>
  The inline job is saved as a regular **Job** entity. You can later fetch
  and manage it via the Jobs API using the `jobId` returned in the interview
  object.
</Info>

## Test Mode

Test mode allows you to create test interviews that immediately complete without consuming billing minutes. This is useful for testing webhook handlers and integration flows.

### When to Use Test Mode

* **Testing Webhook Handlers**: Verify that your webhook endpoints correctly handle `interview.completed` and `analysis.completed` events
* **Integration Testing**: Test your application's interview processing logic without waiting for real interviews
* **Development**: Develop and debug features that depend on completed interviews
* **Demo Purposes**: Create sample interviews for demonstrations

### How Test Mode Works

When you set `isTest: true`:

1. **Billing Bypass**: All billing checks are skipped - no minutes are consumed
2. **Immediate Completion**: The interview is created with `COMPLETED` status immediately
3. **Mock Analysis Data**: Realistic screening analysis data is automatically generated and stored
4. **Webhook Events**: Both `interview.completed` and `analysis.completed` webhook events are triggered
5. **Default Duration**: Test interviews have a default duration of 5 minutes

### Example: Creating a Test Interview

```javascript theme={null}
const testInterview = await createInterview({
  candidate: {
    firstName: "Jane",
    lastName: "Doe",
    email: "jane@example.com",
    phoneNumber: "+1234567890",
    gdprExpiryDate: "2026-11-16",
  },
  agentId: "agent-uuid",
  isTest: true, // Enable test mode
});

console.log(`Test interview created: ${testInterview.id}`);
console.log(`Status: ${testInterview.status}`); // "COMPLETED"
console.log(`Duration: ${testInterview.durationMinutes} minutes`); // 5
```

### Test Interview Characteristics

* **Status**: Always `COMPLETED` immediately
* **Duration**: 5 minutes (300 seconds)
* **Analysis**: Includes mock screening analysis with:
  * Conversation check results (candidateInterest: true, conversationCompleted: true)
  * Candidate analysis scores and recommendations
  * Mock transcript segments
* **Webhooks**: Triggers both `interview.completed` and `analysis.completed` events
* **Billing**: No minutes consumed, no billing checks performed

<Info>
  Test interviews are marked with `isTest: true` in their metadata. They appear in interview lists and can be queried like normal interviews, but they do not affect billing or production metrics.
</Info>

## Related Resources

<CardGroup cols={2}>
  <Card title="Interviews Resource Guide" icon="microphone" href="/guides/resources/interviews">
    Learn about interview management and analysis
  </Card>

  <Card title="Agents Resource Guide" icon="robot" href="/guides/resources/agents">
    Configure AI interview agents
  </Card>

  <Card title="Candidates Resource Guide" icon="user" href="/guides/resources/candidates">
    Manage candidate profiles
  </Card>

  <Card title="Billing Guide" icon="credit-card" href="/guides/resources/billing">
    Understand interview costs and limits
  </Card>

  <Card title="Webhooks Guide" icon="webhook" href="/guides/webhooks">
    Learn about webhook events and testing
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /interviews
openapi: 3.0.0
info:
  title: InstaView API
  description: |-
    InstaView API Documentation

    ## Authentication

    All endpoints require API key authentication using Bearer token:
    ```
    Authorization: Bearer sk_your_api_key_here
    ```

    ## API Key Management

    The API Key module provides comprehensive key management for:
    - **Direct Client Keys**: Company-scoped keys for your applications
    - **ATS Partner Keys**: Resource-scoped keys for ATS integrations

    ### Key Features
    - HMAC-SHA256 hashing for API key storage
    - Configurable rate limiting
    - Comprehensive audit logging
    - Company-level isolation
    - Resource scoping for ATS partners
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.instaview.sk
    description: Production API Gateway
security: []
tags: []
paths:
  /interviews:
    post:
      tags:
        - Interviews
      summary: Create interview
      description: >-
        Creates an interview for a candidate using an existing or inline
        candidate/agent/job, scoped to the API key's company. Respects company
        billing limits and subscription plans. Set isTest=true to create a test
        interview that immediately completes without consuming billing minutes.
      operationId: PublicInterviewsController_createInterview_v1
      parameters:
        - name: companyId
          required: false
          in: query
          description: >-
            Required for ATS API keys to specify which company to access.
            Ignored for standard company API keys.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicCreateInterviewDto'
      responses:
        '200':
          description: OK (legacy; prefer 201)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicInterviewDto'
        '201':
          description: Interview created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicInterviewDto'
        '400':
          description: Bad Request - Validation error or invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingJobId:
                  summary: Missing jobId for multi-job candidate
                  value:
                    statusCode: 400
                    message: >-
                      Job ID must be provided when candidate has multiple job
                      assignments
                    error: Bad Request
                xorViolation:
                  summary: XOR constraint violation (candidateId vs candidate)
                  value:
                    statusCode: 400
                    message: >-
                      Either candidateId or candidate must be provided, but not
                      both.
                    error: Bad Request
                jobXorViolation:
                  summary: XOR constraint violation (jobId vs job)
                  value:
                    statusCode: 400
                    message: >-
                      Either jobId or job must be provided, but not both. You
                      may also provide neither.
                    error: Bad Request
        '401':
          description: Unauthorized - Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingBearer:
                  summary: Missing Bearer token
                  value:
                    statusCode: 401
                    message: Unauthorized
                    error: Unauthorized
        '403':
          description: Forbidden - Access denied or billing limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found - Resource not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too Many Requests - Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearer: []
components:
  schemas:
    PublicCreateInterviewDto:
      type: object
      additionalProperties: false
      oneOf:
        - required:
            - candidateId
          not:
            required:
              - candidate
        - required:
            - candidate
          not:
            required:
              - candidateId
      allOf:
        - oneOf:
            - required:
                - agentId
              not:
                required:
                  - agent
            - required:
                - agent
              not:
                required:
                  - agentId
        - oneOf:
            - required:
                - jobId
              not:
                required:
                  - job
            - required:
                - job
              not:
                required:
                  - jobId
            - not:
                anyOf:
                  - required:
                      - jobId
                  - required:
                      - job
      properties:
        candidateId:
          type: string
          description: >-
            Existing candidate ID (XOR with candidate). Must exist and belong to
            the same company as the API key. Existence/company relationship is
            validated server-side.
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        jobId:
          type: string
          description: >-
            Job ID to associate the interview with (XOR with job). Required when
            candidate has multiple job assignments and no job is provided. Must
            belong to the API key's company. If the candidate is not already
            assigned to this job, they will be automatically assigned.
          example: 123e4567-e89b-12d3-a456-426614174000
          format: uuid
        job:
          description: >-
            Job for inline creation (XOR with jobId). When provided, a new job
            will be created and used for the interview. Cannot be combined with
            jobId.
          allOf:
            - $ref: '#/components/schemas/JobDto'
        candidate:
          description: Candidate for inline creation (XOR with candidateId)
          allOf:
            - $ref: '#/components/schemas/CandidateDto'
        agentId:
          type: string
          description: >-
            Existing agent ID (XOR with agent). Must exist and belong to the
            same company as the API key. Existence/company relationship is
            validated server-side.
          format: uuid
          example: 987e6543-e21b-12d3-a456-426614174000
        agent:
          description: Agent for inline creation (XOR with agentId)
          allOf:
            - $ref: '#/components/schemas/AgentDto'
        scheduleTime:
          type: string
          description: Scheduled time in ISO 8601 format (max 30 days in future)
          example: '2025-11-20T10:00:00Z'
          format: date-time
        metadata:
          type: object
          description: Custom metadata for the interview (max 10KB, 5 levels deep, 50 keys)
          example:
            externalInterviewId: INT-789
            interviewerNotes: Focus on technical skills
        isTest:
          type: boolean
          description: >-
            If true, creates a test interview that immediately completes without
            consuming billing minutes. Triggers webhook events
            (interview.completed, analysis.completed) for testing webhook
            handlers.
          example: false
          default: false
      required:
        - scheduleTime
    PublicInterviewDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Interview ID
          example: 123e4567-e89b-12d3-a456-426614174000
        candidateId:
          type: string
          format: uuid
          description: Candidate ID
          example: 987e6543-e21b-12d3-a456-426614174000
        agentId:
          type: string
          description: Agent ID
          format: uuid
          example: 456e7890-e12b-34d5-a678-901234567890
        jobId:
          type: string
          description: Job ID associated with this interview, if any
          format: uuid
          nullable: true
          example: 123e4567-e89b-12d3-a456-426614174000
        status:
          type: string
          description: Interview status
          enum:
            - UNDEFINED
            - SCHEDULED
            - CANCELLED
            - FAILED
            - COMPLETED
            - IN_PROGRESS
          example: SCHEDULED
        scheduledAt:
          type: string
          format: date-time
          description: Scheduled time
          example: '2025-11-20T10:00:00Z'
        durationMinutes:
          type: number
          description: Interview duration in minutes
          example: 15
        finishedDate:
          type: string
          format: date-time
          description: Finished date
          example: '2025-11-20T10:15:00Z'
        metadata:
          type: object
          description: Custom metadata
          example:
            externalInterviewId: INT-789
        callAttempts:
          description: >-
            Call attempt logs for this interview. Present for phone interviews,
            typically empty or undefined for online interviews.
          type: array
          items:
            $ref: '#/components/schemas/PublicCallAttemptDto'
        analysis:
          description: >-
            Candidate analysis data. Present only if analysis has been
            generated.
          allOf:
            - $ref: '#/components/schemas/PublicCandidateAnalysisDto'
        createdAt:
          type: string
          description: Created timestamp
          example: '2024-11-16T10:30:00Z'
        updatedAt:
          type: string
          description: Updated timestamp
          example: '2024-11-16T10:30:00Z'
        isTest:
          type: boolean
          description: >-
            Whether this is a test interview. Test interviews are created with
            isTest=true, immediately complete without consuming billing minutes,
            and are excluded from billing/usage summaries. Use test interviews
            for testing webhook handlers and integration flows.
          example: false
      required:
        - id
        - candidateId
        - agentId
        - status
        - scheduledAt
        - createdAt
        - updatedAt
    ErrorResponse:
      type: object
      properties:
        statusCode:
          type: integer
          example: 400
        message:
          type: string
          example: Validation failed
        error:
          type: string
          example: Bad Request
      required:
        - statusCode
        - message
    JobDto:
      type: object
      additionalProperties: false
      allOf:
        - $ref: '#/components/schemas/PublicCreateJobDto'
      description: Job for inline creation used in interview creation
    CandidateDto:
      type: object
      additionalProperties: false
      properties:
        firstName:
          type: string
          description: Candidate's first name
          example: John
          minLength: 1
          maxLength: 100
        lastName:
          type: string
          description: Candidate's last name
          example: Doe
          minLength: 1
          maxLength: 100
        email:
          type: string
          description: Candidate's email address
          example: john.doe@example.com
        phoneNumber:
          type: string
          description: Candidate's phone number in E.164 format (must start with +)
          example: '+421915123456'
          pattern: ^\+[1-9]\d{1,14}$
        jobId:
          type: string
          description: >-
            Optional Job ID to associate the candidate with. Must belong to the
            same company as the API key. Note: When CandidateDto is used inline
            within interview creation, this field is ignored; use the top-level
            jobId/job instead.
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        gdprExpiryDate:
          type: string
          description: GDPR expiry date in ISO 8601 format (must be in the future)
          example: '2026-11-16'
          format: date
        gender:
          type: string
          description: >-
            Candidate's gender. Used for gender-aware addressing in interviews.
            If not provided, gender is auto-detected from the candidate's name.
          enum:
            - male
            - female
          example: female
        workHistory:
          type: array
          description: Optional work history items of the candidate.
          maxItems: 20
          items:
            $ref: '#/components/schemas/PublicCandidateWorkHistoryItemDto'
      required:
        - firstName
        - lastName
        - gdprExpiryDate
    AgentDto:
      type: object
      properties:
        name:
          type: string
          description: Agent name
          example: Senior Developer Interview
          minLength: 2
          maxLength: 100
        type:
          type: string
          description: Type of the agent
          enum:
            - UNDEFINED
            - ONLINE
            - PHONE
          example: ONLINE
        focus:
          type: string
          description: >-
            Focus of the agent. GENERIC: For jobless interviews where candidates
            don't need job assignments. SCREENING: Initial candidate screening
            and assessment. OUTREACH: Candidate outreach and engagement.
            LANGUAGE_TEST: Language proficiency assessment.
          enum:
            - GENERIC
            - SCREENING
            - OUTREACH
            - LANGUAGE_TEST
          example: SCREENING
        language:
          type: string
          description: Language of the interview
          enum:
            - UNDEFINED
            - EN
            - JA
            - ZH
            - DE
            - HI
            - FR
            - KO
            - PT
            - IT
            - ES
            - ID
            - NL
            - TR
            - FIL
            - PL
            - SV
            - BG
            - RO
            - AR
            - CS
            - EL
            - FI
            - HR
            - MS
            - SK
            - DA
            - TA
            - UK
            - RU
            - HU
            - 'NO'
            - VI
          example: EN
        duration:
          type: number
          description: Duration of the interview in minutes
          example: 30
          minimum: 1
          maximum: 180
        questions:
          description: List of questions for the interview
          example:
            - What is your experience with React?
            - Tell me about a challenging project you worked on
          type: array
          items:
            type: string
        instructions:
          type: string
          description: Additional instructions for the interview
          example: Focus on technical skills and previous project experience
        voiceId:
          type: string
          description: Voice ID for the AI interview
          enum:
            - ALEX
            - PETER
            - MIRIAM
            - SUE
            - VIERA
            - CASANDRA
            - SILVIA
            - MICHAEL
            - LUKE
            - EMMA
            - SARAH
            - EVA
        companyPhoneNumberId:
          type: string
          description: >-
            ID of the company phone number assignment to use for calls from this
            agent (CompanyPhoneNumber.id). Required when type=PHONE.
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        cefrLevel:
          type: string
          description: CEFR level for language test agents
          enum:
            - A1
            - A2
            - B1
            - B2
            - C1
            - C2
          example: B1
      allOf:
        - oneOf:
            - properties:
                type:
                  enum:
                    - PHONE
              required:
                - companyPhoneNumberId
            - properties:
                type:
                  not:
                    enum:
                      - PHONE
      required:
        - name
        - type
        - focus
        - language
        - duration
    PublicCallAttemptDto:
      type: object
      properties:
        id:
          type: string
          description: Call attempt ID
          example: c9c9a6e8-fb4a-45f3-80fc-bf94f071cd2a
        direction:
          type: string
          description: Interview direction (inbound / outbound)
          enum:
            - UNDEFINED
            - INBOUND
            - OUTBOUND
          example: OUTBOUND
        status:
          type: string
          description: Current status of the call attempt
          enum:
            - UNDEFINED
            - SCHEDULED
            - IN_PROGRESS
            - COMPLETED
            - NO_ANSWER
            - BUSY
            - FAILED
            - CANCELLED
            - VOICEMAIL
            - REJECTED
            - NO_CONSENT
            - TIMEOUT
            - MAX_ATTEMPTS_REACHED
            - HUMAN_CONTACT_REQUESTED
            - OTHER_ROLE_INTEREST
            - POLITE_DECLINE
            - TIMING_ISSUE
          example: COMPLETED
        reasonCode:
          type: string
          description: Machine-readable reason code for failures or special outcomes
          example: NO_ANSWER
        notes:
          type: string
          description: Human-readable notes associated with this call attempt
          example: Candidate did not pick up, mailbox full
        retryNumber:
          type: number
          description: >-
            Retry number for this attempt (starting from 0 or 1 depending on
            implementation)
          example: 2
        recordingUrl:
          type: string
          description: URL to the call recording, if available
          example: https://audio.example.com/recording.mp3
        duration:
          type: number
          description: Duration of the call attempt in seconds
          example: 180
        scheduledAt:
          type: string
          format: date-time
          description: Scheduled time for this call attempt (ISO 8601, UTC)
          example: '2025-07-22T10:00:00Z'
        calledAt:
          type: string
          format: date-time
          description: Actual time when the call started (ISO 8601, UTC)
          example: '2025-07-22T10:01:00Z'
        transcript:
          description: >-
            Transcript segments for this call attempt, ordered chronologically.
            Each segment contains the speaker, text content, and timing. Omitted
            when the interview has no transcript or the call attempt did not
            produce one.
          type: array
          items:
            $ref: '#/components/schemas/PublicTranscriptSegmentDto'
      required:
        - id
        - direction
    PublicCandidateAnalysisDto:
      type: object
      properties:
        id:
          type: string
          description: Analysis ID
          example: 123e4567-e89b-12d3-a456-426614174000
        general:
          description: General analysis data
          allOf:
            - $ref: '#/components/schemas/PublicGeneralAnalysisDto'
        specific:
          type: object
          description: >-
            Specific analysis data based on interview type (e.g., language test
            scores, outreach feedback)
          example:
            pronunciationScores:
              accuracy: 90
              fluency: 85
              prosody: 82
            grammar:
              level: C1
      required:
        - id
        - general
    PublicCreateJobDto:
      type: object
      properties:
        title:
          type: string
          description: Job title
          example: Senior TypeScript Developer
          minLength: 5
          maxLength: 200
        description:
          type: string
          description: Job description
          example: We are looking for an experienced TypeScript developer...
          minLength: 10
          maxLength: 5000
        jobUrl:
          type: string
          description: Job URL
          example: https://company.com/careers/senior-typescript-dev
        benefits:
          type: string
          description: Benefits
          example: Health insurance, remote work, flexible hours
        requiredSkills:
          description: Required skills
          example:
            - TypeScript
            - React
            - Node.js
          maxItems: 10
          type: array
          items:
            type: string
        niceToHaveSkills:
          description: Nice-to-have skills
          example:
            - Docker
            - AWS
            - GraphQL
          maxItems: 10
          type: array
          items:
            type: string
        languageRequirements:
          description: Language requirements with proficiency levels
          example:
            - language: EN
              proficiency: B2
            - language: SK
              proficiency: C1
          maxItems: 5
          type: array
          items:
            $ref: '#/components/schemas/PublicLanguageRequirementDto'
        education:
          type: array
          description: Education requirements
          example:
            - BACHELOR_LEVEL
            - MASTER_LEVEL
          items:
            type: string
            enum:
              - UNDEFINED
              - PRIMARY_EDUCATION
              - SECONDARY_SCHOOL_STUDENT
              - SECONDARY_WITHOUT_DIPLOMA
              - SECONDARY_WITH_DIPLOMA
              - POST_SECONDARY_VOCATIONAL
              - UNIVERSITY_STUDENT
              - BACHELOR_LEVEL
              - MASTER_LEVEL
              - POSTGRADUATE
        experience:
          type: string
          description: Experience level required
          enum:
            - UNDEFINED
            - NO_EXPERIENCE
            - LESS_THAN_1_YEAR
            - ONE_TO_3_YEARS
            - THREE_TO_5_YEARS
            - FIVE_TO_10_YEARS
            - TEN_TO_15_YEARS
            - MORE_THAN_15_YEARS
          example: FIVE_TO_10_YEARS
        contractType:
          type: string
          description: Contract type
          enum:
            - UNDEFINED
            - FULL_TIME
            - PART_TIME
            - FREELANCE_CONTRACT
            - TRADE_LICENSE
            - INTERNSHIP
          example: FULL_TIME
        status:
          type: string
          description: Job status
          enum:
            - UNDEFINED
            - OPEN
            - CLOSED
          example: OPEN
          default: OPEN
        location:
          description: Job location
          allOf:
            - $ref: '#/components/schemas/PublicJobLocationDto'
        salary:
          description: >-
            Salary range with comprehensive validation: min and max must be >=
            0, min < max, currency and period are required if min or max is
            provided, at least one of min or max must be provided if any salary
            field is present
          example:
            min: 50000
            max: 80000
            currency: USD
            period: YEARLY
          allOf:
            - $ref: '#/components/schemas/PublicSalaryRangeDto'
        metadata:
          type: object
          description: Custom metadata for extensibility (max 10KB, 5 levels deep, 50 keys)
          example:
            externalJobId: JOB-12345
            department: Engineering
            hiringManager: Jane Doe
      required:
        - title
    PublicCandidateWorkHistoryItemDto:
      type: object
      properties:
        id:
          type: string
          description: Work history item ID
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        companyName:
          type: string
          description: Name of the employer company
          example: Google
          minLength: 1
          maxLength: 255
        candidatePosition:
          type: string
          description: Candidate's job position/title
          example: Software Engineer
          minLength: 1
          maxLength: 255
        referenceName:
          type: string
          description: Name of the reference person
          example: Jane Smith
          maxLength: 255
        referencePhone:
          type: string
          description: Phone number of reference contact in E.164 format
          example: '+1987654321'
          pattern: ^\+[1-9]\d{1,14}$
        startDate:
          type: string
          description: Job start date in calendar format (yyyy-MM-dd)
          example: '2020-01-01'
          format: date
          pattern: ^\d{4}-\d{2}-\d{2}$
        endDate:
          type: string
          description: Job end date in calendar format (yyyy-MM-dd)
          example: '2022-12-31'
          format: date
          pattern: ^\d{4}-\d{2}-\d{2}$
      required:
        - companyName
        - candidatePosition
        - referencePhone
    PublicTranscriptSegmentDto:
      type: object
      description: >-
        A single segment of a call attempt transcript, representing one
        utterance by either the AI interviewer or the candidate.
      properties:
        speaker:
          type: string
          description: Who spoke this segment
          enum:
            - AI
            - HUMAN
          example: AI
        text:
          type: string
          description: Transcribed text of the utterance
          example: Hello, thank you for taking the time to speak with me today.
        startTime:
          type: number
          description: Start time of the segment in seconds from the start of the recording
          example: 0
          minimum: 0
        endTime:
          type: number
          description: End time of the segment in seconds from the start of the recording
          example: 3.5
          minimum: 0
        language:
          type: string
          description: BCP-47 language code detected for this segment (e.g. 'en', 'sk')
          example: en
          pattern: ^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$
      required:
        - speaker
        - text
        - startTime
        - endTime
    PublicGeneralAnalysisDto:
      type: object
      properties:
        overallRating:
          type: number
          description: Overall rating (0-100)
          example: 85
        companyFitRating:
          type: string
          description: Company fit rating
          enum:
            - UNDEFINED
            - LOW
            - MEDIUM
            - HIGH
          example: HIGH
        education:
          type: string
          description: Summary of education analysis
          example: Master's degree in Computer Science
        experience:
          type: string
          description: Summary of experience analysis
          example: 5 years of experience in software development
        strongPoints:
          description: Candidate's strong points and advantages
          example:
            - Excellent communication skills
            - Strong technical expertise in React and Node.js
            - Proven track record of leading teams
          type: array
          items:
            type: string
        weakPoints:
          description: Candidate's weak points or areas for improvement
          example:
            - Limited experience with microservices
            - Needs improvement in system design
          type: array
          items:
            type: string
        evaluation:
          description: Overall evaluation summary and recommendations
          example:
            - Strong candidate with relevant experience
            - Good cultural fit for the team
            - Recommended for next round
          type: array
          items:
            type: string
        status:
          type: number
          description: Analysis processing status
          enum:
            - 1
            - 2
            - 3
            - 4
          example: 3
        createdAt:
          type: string
          description: Created timestamp (UTC)
          example: '2024-11-16T10:30:00Z'
          format: date-time
        updatedAt:
          type: string
          description: Updated timestamp (UTC)
          example: '2024-11-16T10:30:00Z'
          format: date-time
      required:
        - createdAt
        - updatedAt
    PublicLanguageRequirementDto:
      type: object
      properties:
        language:
          type: string
          description: Language
          enum:
            - UNDEFINED
            - EN
            - JA
            - ZH
            - DE
            - HI
            - FR
            - KO
            - PT
            - IT
            - ES
            - ID
            - NL
            - TR
            - FIL
            - PL
            - SV
            - BG
            - RO
            - AR
            - CS
            - EL
            - FI
            - HR
            - MS
            - SK
            - DA
            - TA
            - UK
            - RU
            - HU
            - 'NO'
            - VI
          example: EN
        proficiency:
          type: string
          description: Proficiency level (CEFR)
          enum:
            - UNDEFINED
            - A1
            - A2
            - B1
            - B2
            - C1
            - C2
          example: B2
      required:
        - language
        - proficiency
    PublicJobLocationDto:
      type: object
      properties:
        workMode:
          type: string
          description: Work mode
          enum:
            - UNDEFINED
            - ONSITE
            - REMOTE
            - HYBRID
          example: REMOTE
        street:
          type: string
          description: Street address
          example: Hlavná 123
          minLength: 2
          maxLength: 200
        city:
          type: string
          description: City
          example: Bratislava
          minLength: 2
          maxLength: 100
        postalCode:
          type: string
          description: Postal code
          example: '81101'
          minLength: 2
          maxLength: 20
        countryCode:
          type: string
          description: Country code (ISO 3166-1 alpha-2)
          enum:
            - XX
            - AF
            - AL
            - DZ
            - AS
            - AD
            - AO
            - AI
            - AQ
            - AG
            - AR
            - AM
            - AW
            - AU
            - AT
            - AZ
            - BS
            - BH
            - BD
            - BB
            - BY
            - BE
            - BZ
            - BJ
            - BM
            - BT
            - BO
            - BA
            - BW
            - BR
            - IO
            - BN
            - BG
            - BF
            - BI
            - KH
            - CM
            - CA
            - CV
            - KY
            - CF
            - TD
            - CL
            - CN
            - CX
            - CC
            - CO
            - KM
            - CG
            - CD
            - CK
            - CR
            - CI
            - HR
            - CU
            - CY
            - CZ
            - DK
            - DJ
            - DM
            - DO
            - EC
            - EG
            - SV
            - GQ
            - ER
            - EE
            - SZ
            - ET
            - FK
            - FO
            - FJ
            - FI
            - FR
            - GF
            - PF
            - TF
            - GA
            - GM
            - GE
            - DE
            - GH
            - GI
            - GR
            - GL
            - GD
            - GP
            - GU
            - GT
            - GG
            - GN
            - GW
            - GY
            - HT
            - HM
            - VA
            - HN
            - HK
            - HU
            - IS
            - IN
            - ID
            - IR
            - IQ
            - IE
            - IM
            - IL
            - IT
            - JM
            - JP
            - JE
            - JO
            - KZ
            - KE
            - KI
            - KP
            - KR
            - KW
            - KG
            - LA
            - LV
            - LB
            - LS
            - LR
            - LY
            - LI
            - LT
            - LU
            - MO
            - MG
            - MW
            - MY
            - MV
            - ML
            - MT
            - MH
            - MQ
            - MR
            - MU
            - YT
            - MX
            - FM
            - MD
            - MC
            - MN
            - ME
            - MS
            - MA
            - MZ
            - MM
            - NA
            - NR
            - NP
            - NL
            - NC
            - NZ
            - NI
            - NE
            - NG
            - NU
            - NF
            - MK
            - MP
            - 'NO'
            - OM
            - PK
            - PW
            - PS
            - PA
            - PG
            - PY
            - PE
            - PH
            - PN
            - PL
            - PT
            - PR
            - QA
            - RE
            - RO
            - RU
            - RW
            - BL
            - SH
            - KN
            - LC
            - MF
            - PM
            - VC
            - WS
            - SM
            - ST
            - SA
            - SN
            - RS
            - SC
            - SL
            - SG
            - SX
            - SK
            - SI
            - SB
            - SO
            - ZA
            - GS
            - SS
            - ES
            - LK
            - SD
            - SR
            - SJ
            - SE
            - CH
            - SY
            - TW
            - TJ
            - TZ
            - TH
            - TL
            - TG
            - TK
            - TO
            - TT
            - TN
            - TR
            - TM
            - TC
            - TV
            - UG
            - UA
            - AE
            - GB
            - US
            - UM
            - UY
            - UZ
            - VU
            - VE
            - VN
            - VG
            - VI
            - WF
            - EH
            - YE
            - ZM
            - ZW
          example: SK
    PublicSalaryRangeDto:
      type: object
      properties:
        min:
          type: number
          description: Minimum salary (must be greater than or equal to 0)
          example: 50000
          minimum: 0
        max:
          type: number
          description: Maximum salary (must be greater than or equal to 0)
          example: 80000
          minimum: 0
        currency:
          type: string
          description: Currency (ISO 4217 alpha-3)
          pattern: ^[A-Z]{3}$
          example: USD
        period:
          type: string
          description: Salary period
          enum:
            - UNDEFINED
            - HOURLY
            - DAILY
            - MONTHLY
            - YEARLY
          example: YEARLY
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: API key for authentication using Bearer scheme

````