> ## 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 Candidate

> Creates a new candidate (optionally associated with one or more jobs) in the API key's company.

Creates a new candidate profile. Candidates can optionally be associated with a job or exist in your candidate pool without job assignments. They serve as the foundation for scheduling interviews.

## Overview

The create candidate endpoint allows you to add candidates to your recruitment pipeline. Candidates can optionally be associated with one or more jobs, or exist in your candidate pool without job assignments. Job association can be added at creation time or later. Candidates can be scheduled for interviews using AI agents.

## Use Cases

* **Application Processing**: Create candidates from job applications with job association
* **ATS Integration**: Sync candidates from external ATS systems
* **Manual Entry**: Add candidates discovered through other channels (career fairs, referrals)
* **Candidate Pool**: Build a candidate database without immediate job assignments
* **Bulk Import**: Import multiple candidates for a job posting or general talent pool

## Job Association (Optional)

<Info>
  **Optional Job Assignment**: Candidates can be created with or without a job association via the `jobId` field.

  * **With Job**: Associate candidate with a specific position at creation time.
  * **Without Job**: Create candidate in your talent pool and assign to jobs later via the update endpoint.
  * If provided, the job must exist and belong to your API key's company.
</Info>

## Basic Candidate Creation

### With Job Association

```javascript theme={null}
{
  "jobId": "job-uuid",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "phoneNumber": "+1234567890",
  "gdprExpiryDate": "2026-11-16"
}
```

### Without Job Association (Candidate Pool)

```javascript theme={null}
{
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "phoneNumber": "+1234567890",
  "gdprExpiryDate": "2026-11-16"
}
```

## Comprehensive Candidate Profile

```javascript theme={null}
{
  "jobId": "job-uuid",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "phoneNumber": "+1234567890",
  "gdprExpiryDate": "2026-11-16",
  "gender": "female",
  "metadata": {
    "source": "LinkedIn",
    "externalId": "CAND-12345",
    "notes": "Strong technical background",
    "resumeUrl": "https://storage.example.com/resumes/jane-doe.pdf",
    "linkedinUrl": "https://linkedin.com/in/janedoe"
  },
  "workHistory": [
    {
      "companyName": "Tech Corp",
      "candidatePosition": "Software Engineer",
      "referenceName": "Jane Smith",
      "referencePhone": "+1234567890",
      "startDate": "2020-01-01",
      "endDate": "2022-12-31"
    }
  ]
}
```

<Info>
  **Note**: Fields like `resumeUrl` and `linkedinUrl` are not built-in fields.
  You can store them in the flexible `metadata` object for your custom use
  cases.
</Info>

## Company Scoping

Candidates are scoped to your API key's company. When created with a job association, the job must belong to your company. Candidates created without jobs are automatically associated with your company and can only be accessed via your company's API keys. This ensures complete data isolation between companies.

## Required Fields

<Warning>
  **Required Fields**: All candidates must include:

  * `firstName` — Candidate's first name (1-100 characters)
  * `lastName` — Candidate's last name (1-100 characters)
  * `gdprExpiryDate` — GDPR compliance date in ISO 8601 format (must be in the future, e.g., "2026-11-16")
  * At least one contact method: `email` OR `phoneNumber` (or both)
</Warning>

## Optional Fields

* **jobId**: UUID of job to associate candidate with (job must exist and belong to your company)
* **email**: Valid email address (required if phoneNumber not provided)
* **phoneNumber**: Must be in E.164 format (e.g., `+1234567890`) (required if email not provided)
* **gender**: Candidate's gender (`"male"` or `"female"`). Used for gender-aware addressing in interviews. If not provided, gender is auto-detected from the candidate's name.
* **metadata**: Custom key-value pairs (max 10KB, max 5 levels deep, max 50 keys) for storing additional candidate information

## Field Validation

The API enforces the following validation rules:

* **firstName/lastName**: 1-100 characters (required)
* **gdprExpiryDate**: Must be a valid ISO 8601 date string in the future (required)
* **email**: Must be a valid email format (at least email or phoneNumber required)
* **phoneNumber**: Must start with `+` and follow E.164 format (at least email or phoneNumber required)
* **jobId**: Must be a valid UUID and reference an existing job in your company (optional)
* **gender**: Must be `"male"` or `"female"` if provided (optional)
* **metadata**: Maximum size of 10KB, maximum depth of 5 levels, maximum 50 keys (optional)

## Response Format

The response includes both `jobId` (singular) and `jobIds` (array) fields:

```javascript theme={null}
{
  "id": "candidate-uuid",
  "jobId": "job-uuid",           // First job (for backward compatibility)
  "jobIds": ["job-uuid"],        // Array of all job associations
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "phoneNumber": "+1234567890",
  "gdprExpiryDate": "2026-11-16",
  "gender": "female",
  "status": "APPLIED",
  "workHistory": [
    {
      "id": "work-history-uuid",
      "companyName": "Tech Corp",
      "candidatePosition": "Software Engineer",
      "referenceName": "Jane Smith",
      "referencePhone": "+1234567890",
      "startDate": "2020-01-01",
      "endDate": "2022-12-31"
    }
  ],
  "createdAt": "2025-11-28T10:30:00Z",
  "updatedAt": "2025-11-28T10:30:00Z"
}
```

## Related Resources

<CardGroup cols={2}>
  <Card title="Candidates Resource Guide" icon="user" href="/guides/resources/candidates">
    Learn about candidate management and workflows
  </Card>

  <Card title="Jobs Resource Guide" icon="briefcase" href="/guides/resources/jobs">
    Understand job management
  </Card>

  <Card title="Interviews Resource Guide" icon="microphone" href="/guides/resources/interviews">
    Schedule interviews for candidates
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/candidates/list-candidates">
    List and manage candidates
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /candidates
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:
  /candidates:
    post:
      tags:
        - Candidates
      summary: Create candidate
      description: >-
        Creates a new candidate (optionally associated with one or more jobs) in
        the API key's company.
      operationId: PublicCandidatesController_createCandidate_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/PublicCreateCandidateDto'
      responses:
        '201':
          description: Candidate created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicCandidateDto'
      security:
        - bearer: []
components:
  schemas:
    PublicCreateCandidateDto:
      type: object
      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
          example: '+421915123456'
          pattern: ^\+[1-9]\d{1,14}$
        gdprExpiryDate:
          type: string
          description: GDPR expiry date in ISO 8601 format (must be in the future)
          example: '2026-11-16'
          format: date
        jobId:
          type: string
          description: '[Deprecated - use jobIds] Optional single job ID to associate.'
          deprecated: true
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        jobIds:
          type: array
          description: >-
            Optional array of job IDs to associate the candidate with. If both
            jobId and jobIds are provided, jobIds takes precedence.
          items:
            type: string
            format: uuid
          uniqueItems: true
          minItems: 1
          maxItems: 50
        metadata:
          type: object
          description: >-
            Custom metadata for extensibility (key-value pairs, max 10KB, 5
            levels deep, 50 keys)
          example:
            source: LinkedIn
            referredBy: Jane Smith
            tags:
              - senior
              - remote-preferred
            externalId: CAND-12345
        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
        cvText:
          type: string
          description: >-
            The candidate's CV in plain text. This will be automatically
            anonymized.
          example: |-
            Jane Doe
            Software Engineer
            Experience: ...
          maxLength: 50000
        workHistory:
          type: array
          description: Optional work history items of the candidate.
          maxItems: 20
          items:
            $ref: '#/components/schemas/PublicCandidateWorkHistoryItemDto'
      required:
        - firstName
        - lastName
        - gdprExpiryDate
    PublicCandidateDto:
      type: object
      properties:
        id:
          type: string
          description: Candidate ID
          example: 123e4567-e89b-12d3-a456-426614174000
        jobId:
          type: string
          description: '[Deprecated] Single job ID; use jobIds instead.'
          deprecated: true
          example: 987e6543-e21b-12d3-a456-426614174000
        jobIds:
          type: array
          description: Jobs the candidate is assigned to.
          items:
            type: string
            format: uuid
          uniqueItems: true
          maxItems: 50
        firstName:
          type: string
          description: Candidate's first name
          example: John
        lastName:
          type: string
          description: Candidate's last name
          example: Doe
        email:
          type: string
          description: Candidate's email address
          example: john.doe@example.com
        phoneNumber:
          type: string
          description: Candidate's phone number
          example: '+421915123456'
        status:
          type: string
          description: Candidate status
          enum:
            - UNDEFINED
            - APPLIED
            - IN_PROCESS
            - REJECTED
            - ACCEPTED
          example: APPLIED
        gdprExpiryDate:
          type: string
          description: >-
            GDPR expiry date. Currently returned as a date (no time). NOTE: We
            plan to migrate to a timestamp with timezone (timestamptz) for
            global correctness.
          example: '2026-11-16'
          format: date
        overallRating:
          type: number
          description: Overall rating/match score (0-100)
          example: 85
          minimum: 0
          maximum: 100
        metadata:
          type: object
          description: Custom metadata
          example:
            source: LinkedIn
            externalId: CAND-12345
        createdAt:
          type: string
          description: Created timestamp (UTC)
          example: '2025-11-20T10:30:00Z'
          format: date-time
        updatedAt:
          type: string
          description: Updated timestamp (UTC)
          example: '2025-11-20T10:30:00Z'
          format: date-time
        analysisCount:
          type: number
          description: Number of analyses for this candidate (for quick overview)
          example: 2
        interviewCount:
          type: number
          description: Number of interviews for this candidate (for quick overview)
          example: 3
        links:
          type: object
          description: >-
            Convenience links to related collections. Endpoints may be added
            incrementally.
          example:
            analyses: >-
              /v1/public/candidates/123e4567-e89b-12d3-a456-426614174000/analyses
            interviews: >-
              /v1/public/candidates/123e4567-e89b-12d3-a456-426614174000/interviews
        gender:
          type: string
          description: >-
            Candidate's gender. Used for gender-aware addressing in interviews.
            Null if not explicitly set (auto-detected from name).
          enum:
            - male
            - female
          nullable: true
          example: female
        anonymizedCvText:
          type: string
          description: The candidate's anonymized CV in plain text.
          example: |-
            [NAME]
            Software Engineer
            Experience: ...
        workHistory:
          type: array
          description: Work history items of the candidate.
          maxItems: 20
          items:
            $ref: '#/components/schemas/PublicCandidateWorkHistoryItemDto'
      required:
        - id
        - firstName
        - lastName
        - status
        - createdAt
        - updatedAt
    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
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: API key for authentication using Bearer scheme

````