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

# Add a candidate

> Create a new candidate in your company.

- **Duplicate email handling:** if a candidate with the same email
  already exists, the existing candidate is returned with
  `isExisting: true` instead of creating a duplicate.
- **Job association:** if `jobId` is provided, the candidate is
  associated with that job and `jobCandidateId` is returned; resume
  scoring is automatically enabled (consumes credits). If the
  candidate is already in the job, `isAlreadyInJob` is `true` in the
  response.
- **Resume parsing:** by default (`shouldParseResume: true`), a
  provided `resume` URL is downloaded, stored, and parsed
  asynchronously (consumes credits). The webhook events
  `resume.single_parse.completed` and `resume.single_parse.failed`
  are sent when parsing completes or fails.
- **Scoring without parsing:** if `shouldParseResume` is `false` and
  `jobId` is provided, you must include `city`, `country`,
  `educations`, and `workExperiences` for scoring to work; otherwise
  the request fails with `MISSING_SCORING_FIELDS` (the missing field
  names are listed in `details.missingFields`).
- **Response structure:** all miscellaneous fields (educations,
  workExperiences, etc.) are flattened to the top level of the
  returned candidate object.
- **Validation:** all fields are validated against a schema; invalid
  requests return detailed field-specific error messages.




## OpenAPI

````yaml /api-reference/openapi.yaml post /candidates
openapi: 3.1.0
info:
  title: TapTalent Partner API
  version: 1.0.0
  summary: Partner API for jobs, candidates, pipelines, custom fields, and webhooks.
  description: >
    The TapTalent Partner API lets partner systems manage jobs, candidates,

    job-candidate relationships, hiring pipelines, and custom fields, and

    receive real-time event notifications via webhooks. All communication is

    JSON over HTTPS.


    ## Authentication


    Every request requires an API key sent as an HTTP bearer token:


    ```

    Authorization: Bearer sk_live_AbCdEfGhIjKlMnOpQrStUv

    ```


    Keys are prefixed `sk_live_` (production) or `sk_test_` (sandbox) followed

    by 22 base62 characters, are scoped to a company, and are generated from

    the TapTalent dashboard (Account Settings → Developers → API Key

    Management). Key management is dashboard-only and not available via this

    API.


    ## Response envelopes


    The API uses three envelope styles, by resource family:


    | Family | Success envelope |

    |---|---|

    | Jobs | Bare object (e.g. `{ "jobs": [...], "totalJobs": 45 }` or the job
    object itself) |

    | Candidates, Job Candidates, Pipelines, Custom Fields | `{ "status":
    "success", "data": ... }` |

    | Bulk resume upload and batch retrieval | `{ "success": true, "data": ...
    }` |


    Each operation in this specification models its family's actual envelope;

    no unified envelope is imposed.


    ## Pagination


    Pagination conventions vary by endpoint and are modeled as documented:


    | Endpoint | Page parameter | First page | Default page size | Page size
    rule |

    |---|---|---|---|---|

    | `GET /jobs` | `pageNumber` | 1 | 10 | one of 10, 20, 40, 80, 100 |

    | `GET /candidates/list` | `pageNumber` | **0** | 10 | one of 10, 20, 40,
    80, 100 |

    | `GET /candidates/batch/{batchId}` | `pageNumber` | 1 | 10 | one of 10, 20,
    40, 80, 100 |

    | `GET /job-candidates/job/{jobId}/candidates` | `page` | 1 | 20 | one of
    10, 20, 40, 80, 100 |

    | `GET /job-candidates/stage/{stageId}/candidates` | `page` | 1 | 20 | any
    value from 1 to 100 |


    ## Errors


    Most errors use the canonical envelope:


    ```json

    {
      "error": {
        "code": "ERROR_CODE",
        "type": "error_type",
        "message": "Human-readable error message",
        "details": { "field": "Specific validation error message" }
      }
    }

    ```


    Authentication failures use flat shapes instead (`{"message": ...}`,

    `{"code": ..., "message": ...}` or `{"message": ..., "isApiKeyExists":

    false}`); see the shared 401 response. Rate limits are applied at the

    company level; numeric limits and the 429 response body are not yet

    published.


    ## Webhooks


    Event notifications are delivered as HTTP POST requests to a single

    company-level HTTPS endpoint configured in the dashboard. Deliveries carry

    the headers `X-Webhook-Event`, `X-Webhook-Timestamp`, and `X-Webhook-Key`

    (verify by plain equality against the key generated in the dashboard;

    HMAC signatures are not yet available). Endpoints must respond with a 2xx

    status within 5 seconds; failed deliveries are retried at 200 ms, 400 ms,

    and 800 ms before being marked failed. See the `webhooks` section of this

    document for every event payload.


    ## Conventions used in this specification


    - `x-inferred: true` marks schemas or responses whose shape is inferred
      from related endpoints because the source documentation does not include
      an example; verify against the sandbox before relying on exact field
      names.
    - `x-known-quirk` marks fields whose wire format deviates from the API's
      prevailing conventions (for example an epoch timestamp where other
      endpoints return ISO 8601 strings).
    - Where the published documentation shows placeholder string identifiers
      (for example `"pipelineId_1"` or `"companyId_1"`), this specification
      models the underlying integer identifier types used by the API and notes
      the resolution on the affected field.
  contact:
    name: TapTalent Support
    email: support@taptalent.ai
    url: https://docs.taptalent.io
  license:
    name: Proprietary
    url: https://taptalent.ai
servers:
  - url: https://partner-api.taptalent.io/v1/partner
    description: Production (use `sk_live_` keys)
  - url: https://sandbox.partner-api.taptalent.io/v1/partner
    description: Sandbox / staging (use `sk_test_` keys)
security:
  - bearerAuth: []
tags:
  - name: Jobs
    description: Create, read, update, and list jobs.
  - name: Candidates
    description: >-
      Create and retrieve candidates, upload resumes in bulk, and fetch
      candidates by batch or id list.
  - name: Job Candidates
    description: >-
      Manage the relationship between candidates and jobs, including stage
      placement and per-job resume ingestion.
  - name: Pipelines
    description: Manage hiring pipelines and their stages.
  - name: Custom Fields
    description: Define custom field templates for candidates and jobs.
  - name: Custom Field Values
    description: Read and write custom field values attached to candidates and jobs.
  - name: Webhooks
    description: >-
      Event notifications delivered to your configured webhook endpoint. See the
      top-level `webhooks` section for payloads.
paths:
  /candidates:
    post:
      tags:
        - Candidates
      summary: Add a candidate
      description: |
        Create a new candidate in your company.

        - **Duplicate email handling:** if a candidate with the same email
          already exists, the existing candidate is returned with
          `isExisting: true` instead of creating a duplicate.
        - **Job association:** if `jobId` is provided, the candidate is
          associated with that job and `jobCandidateId` is returned; resume
          scoring is automatically enabled (consumes credits). If the
          candidate is already in the job, `isAlreadyInJob` is `true` in the
          response.
        - **Resume parsing:** by default (`shouldParseResume: true`), a
          provided `resume` URL is downloaded, stored, and parsed
          asynchronously (consumes credits). The webhook events
          `resume.single_parse.completed` and `resume.single_parse.failed`
          are sent when parsing completes or fails.
        - **Scoring without parsing:** if `shouldParseResume` is `false` and
          `jobId` is provided, you must include `city`, `country`,
          `educations`, and `workExperiences` for scoring to work; otherwise
          the request fails with `MISSING_SCORING_FIELDS` (the missing field
          names are listed in `details.missingFields`).
        - **Response structure:** all miscellaneous fields (educations,
          workExperiences, etc.) are flattened to the top level of the
          returned candidate object.
        - **Validation:** all fields are validated against a schema; invalid
          requests return detailed field-specific error messages.
      operationId: createCandidate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCandidateRequest'
            examples:
              fullCandidate:
                summary: Candidate with parsed data, resume, and job association
                value:
                  firstName: John
                  lastName: Doe
                  email: john.doe@example.com
                  phone: '+1234567890'
                  resume: https://example.com/resumes/john-doe.pdf
                  currentJobTitle: Software Engineer
                  currentCompany: Tech Corp
                  city: San Francisco
                  country: United States
                  skills:
                    - JavaScript
                    - React
                    - Node.js
                  linkedin: https://linkedin.com/in/johndoe
                  coverLetter: I am interested in joining your team...
                  gender: Male
                  dateOfBirth: '1995-05-15'
                  nationality: American
                  industry: Technology
                  category: Engineering
                  jobId: 12345
                  shouldParseResume: true
                  majors: Computer Science
                  summary: Experienced software engineer with 5+ years...
                  languages:
                    - English
                    - Spanish
                  educations:
                    - degree: Bachelor's
                      university: University of California
                      graduation_year: '2019'
                  workExperiences:
                    - title: Senior Software Engineer
                      company: Tech Corp
                      start_date: '2020-01-01'
                      responsibilities:
                        - Led development of...
                        - Managed team of 5 engineers
                  projectExperiences:
                    - title: E-commerce Platform
                      technology_used: React, Node.js, PostgreSQL
                      summary:
                        - Built a full-stack e-commerce platform...
                        - Implemented payment gateway integration
                  certifications:
                    - name: AWS Certified Solutions Architect
                      provider: Amazon Web Services
                  githubUrl: https://github.com/johndoe
              minimalWithResumeParsing:
                summary: Minimal candidate with resume URL and job association
                value:
                  firstName: John
                  lastName: Doe
                  email: john.doe@example.com
                  phone: '+1234567890'
                  currentJobTitle: Software Engineer
                  currentCompany: Tech Corp
                  city: San Francisco
                  country: United States
                  skills:
                    - JavaScript
                    - React
                    - Node.js
                  resume: https://example.com/resumes/john-doe.pdf
                  jobId: 12345
                  shouldParseResume: true
      responses:
        '200':
          description: |
            Candidate created (or existing candidate returned when the email
            already exists).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateCandidateResponse'
              examples:
                created:
                  summary: Newly created candidate associated with a job
                  value:
                    status: success
                    data:
                      candidate:
                        id: 12345
                        firstName: John
                        lastName: Doe
                        email: john.doe@example.com
                        phone: '+1234567890'
                        currentJobTitle: Software Engineer
                        currentCompany: Tech Corp
                        city: San Francisco
                        country: United States
                        skills:
                          - JavaScript
                          - React
                          - Node.js
                        resume: https://storage.example.com/resumes/john-doe.pdf
                        coverLetter: I am interested in joining your team...
                        majors:
                          - Computer Science
                        summary: Experienced software engineer with 5+ years...
                        languages:
                          - English
                          - Spanish
                        educations:
                          - degree: Bachelor's
                            field: Computer Science
                            institution: University of California
                            startDate: '2015-09-01'
                            endDate: '2019-06-01'
                        workExperiences:
                          - title: Senior Software Engineer
                            company: Tech Corp
                            location: San Francisco, CA
                            startDate: '2020-01-01'
                            endDate: null
                            description: Led development of...
                        projectExperiences:
                          - name: E-commerce Platform
                            description: Built a full-stack e-commerce platform...
                            technologies:
                              - React
                              - Node.js
                              - PostgreSQL
                        certifications:
                          - name: AWS Certified Solutions Architect
                            issuer: Amazon Web Services
                            issueDate: '2022-03-15'
                            expiryDate: '2025-03-15'
                        githubUrl: https://github.com/johndoe
                        linkedin: https://linkedin.com/in/johndoe
                        gender: Male
                        dateOfBirth: '1995-05-15'
                        nationality: American
                        industry: Technology
                        category: Engineering
                      jobCandidateId: 67890
                      isExisting: false
                      isAlreadyInJob: false
        '400':
          description: |
            Validation error. HTTP status inferred from the error category;
            the source documentation specifies the body but not the status
            code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                missingFirstName:
                  summary: Missing firstName
                  value:
                    error:
                      code: MISSING_FIRST_NAME
                      type: validation_error
                      message: firstName is required
                missingLastName:
                  summary: Missing lastName
                  value:
                    error:
                      code: MISSING_LAST_NAME
                      type: validation_error
                      message: lastName is required
                missingEmail:
                  summary: Missing email
                  value:
                    error:
                      code: MISSING_EMAIL
                      type: validation_error
                      message: email is required
                invalidRequest:
                  summary: Invalid request (field-specific validation errors)
                  value:
                    error:
                      code: INVALID_REQUEST
                      type: validation_error
                      message: One or more fields are invalid.
                      details:
                        email: email must be a valid email address
                        resume: >-
                          resume must be a valid URL starting with http:// or
                          https://
                        firstName: firstName is required
                missingScoringFields:
                  summary: Missing scoring fields (scoring without parsing)
                  value:
                    error:
                      code: MISSING_SCORING_FIELDS
                      type: validation_error
                      message: >-
                        When scoring is required (jobId provided) without
                        parsing, these fields are required: educations,
                        workExperiences, city, country
                      details:
                        missingFields:
                          - city
                          - country
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: |
            Insufficient credits for resume parsing or resume scoring. HTTP
            status inferred from the error category (`payment_error`); the
            source documentation specifies the body but not the status code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                insufficientCreditsParsing:
                  summary: Insufficient credits for resume parsing
                  value:
                    error:
                      code: INSUFFICIENT_CREDITS
                      type: payment_error
                      message: Insufficient credits for resume parsing
                insufficientCreditsScoring:
                  summary: Insufficient credits for resume scoring
                  value:
                    error:
                      code: INSUFFICIENT_CREDITS
                      type: payment_error
                      message: Insufficient credits for resume scoring
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CreateCandidateRequest:
      type: object
      description: |
        Request body for creating a candidate. Note that the nested request
        objects (educations, workExperiences, projectExperiences,
        certifications) use different field names than the corresponding
        response objects — see each Input schema's description.
      required:
        - firstName
        - lastName
        - email
      properties:
        firstName:
          type: string
          minLength: 1
          maxLength: 200
          description: Candidate's first name (min 1, max 200 characters).
        lastName:
          type: string
          minLength: 1
          maxLength: 200
          description: Candidate's last name (min 1, max 200 characters).
        email:
          type: string
          format: email
          maxLength: 500
          description: >-
            Candidate's email address (must be valid email format, max 500
            characters).
        phone:
          type: string
          description: Candidate's phone number.
        resume:
          type: string
          format: uri
          description: |
            URL to candidate's resume file (must start with http:// or
            https://). If provided and `shouldParseResume` is true, the resume
            will be downloaded, stored, and parsed.
        currentJobTitle:
          type: string
          description: Candidate's current job title.
        currentCompany:
          type: string
          description: Candidate's current company name.
        city:
          type: string
          description: |
            City location. Required (together with `country`, `educations`,
            and `workExperiences`) when `jobId` is provided and
            `shouldParseResume` is false.
        country:
          type: string
          description: |
            Country. Required (together with `city`, `educations`, and
            `workExperiences`) when `jobId` is provided and
            `shouldParseResume` is false.
        skills:
          description: |
            Array of skills (max 200 characters each) or a comma-separated
            string. Arrays will be converted to comma-separated strings.
          oneOf:
            - type: array
              items:
                type: string
                maxLength: 200
            - type: string
        linkedin:
          type: string
          description: LinkedIn profile URL.
        coverLetter:
          type: string
          description: Cover letter text.
        gender:
          type: string
          description: >-
            Gender. Must be one of: "male", "female", "other", "Male", "Female",
            "Other".
          enum:
            - male
            - female
            - other
            - Male
            - Female
            - Other
        dateOfBirth:
          type: string
          format: date
          description: Date of birth (ISO 8601 format).
        nationality:
          type: string
          description: Nationality.
        industry:
          type: string
          description: Industry.
        category:
          type: string
          description: Category.
        jobId:
          type: integer
          description: |
            Job ID to associate the candidate with. If provided, resume
            scoring will be automatically enabled (consumes credits).
        shouldParseResume:
          type: boolean
          default: true
          description: |
            Whether to parse the resume. Default: `true`. Set to `false` if
            you're providing parsed data directly (educations,
            workExperiences, etc.). If `false` and `jobId` is provided,
            `city`, `country`, `educations`, and `workExperiences` are
            required for scoring to work.
        majors:
          type: string
          description: |
            Majors/fields of study (comma-separated string or single value).
            Note: a string on input, but returned as an array of strings in
            responses.
        summary:
          type: string
          maxLength: 5000
          description: Professional summary (max 5000 characters).
        languages:
          type: array
          description: Array of language strings (max 100 characters each).
          items:
            type: string
            maxLength: 100
        educations:
          type: array
          description: |
            Array of education objects. Required (together with `city`,
            `country`, and `workExperiences`) when `jobId` is provided and
            `shouldParseResume` is false.
          items:
            $ref: '#/components/schemas/CandidateEducationInput'
        githubUrl:
          type: string
          format: uri
          description: GitHub profile URL (must be valid URL).
        certifications:
          type: array
          description: Array of certification objects.
          items:
            $ref: '#/components/schemas/CandidateCertificationInput'
        workExperiences:
          type: array
          description: |
            Array of work experience objects. Required (together with `city`,
            `country`, and `educations`) when `jobId` is provided and
            `shouldParseResume` is false.
          items:
            $ref: '#/components/schemas/CandidateWorkExperienceInput'
        projectExperiences:
          type: array
          description: Array of project experience objects.
          items:
            $ref: '#/components/schemas/CandidateProjectExperienceInput'
    CreateCandidateResponse:
      type: object
      description: Success envelope for the create-candidate endpoint.
      required:
        - status
        - data
      properties:
        status:
          type: string
          description: Response status ("success").
          enum:
            - success
        data:
          type: object
          required:
            - candidate
            - jobCandidateId
            - isExisting
          properties:
            candidate:
              $ref: '#/components/schemas/CandidateProfile'
              description: >-
                The created or existing candidate object with all fields
                flattened.
            jobCandidateId:
              type:
                - integer
                - 'null'
              description: |
                The job candidate ID if `jobId` was provided and the candidate
                was added to the job, otherwise `null`.
            isExisting:
              type: boolean
              description: |
                Indicates if the candidate already existed (true) or was newly
                created (false).
            isAlreadyInJob:
              type: boolean
              description: |
                Indicates if the candidate was already associated with the
                specified job. Only present when `jobId` is provided in the
                request.
    ApiError:
      type: object
      description: Canonical error envelope used by most non-authentication errors.
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ApiErrorBody'
    CandidateEducationInput:
      type: object
      description: |
        Education object as accepted in the create-candidate request. Note:
        this request shape (`degree`, `university`, `graduation_year`) differs
        from the response shape `CandidateEducation` (`degree`, `field`,
        `institution`, `startDate`, `endDate`).
      properties:
        degree:
          type: string
          maxLength: 500
          description: Degree name (max 500 characters).
        university:
          type: string
          maxLength: 500
          description: University/institution name (max 500 characters).
        graduation_year:
          type: string
          maxLength: 50
          description: Graduation year (max 50 characters).
    CandidateCertificationInput:
      type: object
      description: |
        Certification object as accepted in the create-candidate request.
        Note: this request shape (`name`, `provider`) differs from the
        response shape `CandidateCertification` (`name`, `issuer`,
        `issueDate`, `expiryDate`).
      required:
        - name
        - provider
      properties:
        name:
          type: string
          maxLength: 500
          description: Certification name (max 500 characters).
        provider:
          type: string
          maxLength: 500
          description: Certification provider/issuer (max 500 characters).
    CandidateWorkExperienceInput:
      type: object
      description: |
        Work experience object as accepted in the create-candidate request.
        Note: this request shape (`title`, `company`, `start_date`,
        `end_date`, `responsibilities`) differs from the response shape
        `CandidateWorkExperience` (`title`, `company`, `location`,
        `startDate`, `endDate`, `description`).
      properties:
        title:
          type: string
          maxLength: 500
          description: Job title (max 500 characters).
        company:
          type: string
          maxLength: 500
          description: Company name (max 500 characters).
        start_date:
          type: string
          maxLength: 50
          description: Start date (max 50 characters).
        end_date:
          type: string
          maxLength: 50
          description: End date (max 50 characters). Omit this field for current positions.
        responsibilities:
          type: array
          description: Array of responsibility strings (max 2000 characters each).
          items:
            type: string
            maxLength: 2000
    CandidateProjectExperienceInput:
      type: object
      description: |
        Project experience object as accepted in the create-candidate request.
        Note: this request shape (`title`, `technology_used`, `summary`)
        differs from the response shape `CandidateProjectExperience` (`name`,
        `description`, `technologies`).
      properties:
        title:
          type: string
          maxLength: 500
          description: Project title (max 500 characters).
        technology_used:
          type: string
          maxLength: 1000
          description: Technologies used (max 1000 characters).
        summary:
          type: array
          description: Array of summary strings (max 2000 characters each).
          items:
            type: string
            maxLength: 2000
    CandidateProfile:
      type: object
      description: |
        Full candidate object with flattened structure (miscellaneous fields
        such as educations and workExperiences are extracted to the top
        level), as returned by the create-candidate endpoint.
      properties:
        id:
          type: integer
          description: Unique candidate identifier.
        firstName:
          type: string
          description: Candidate's first name.
        lastName:
          type: string
          description: Candidate's last name.
        email:
          type: string
          description: Candidate's email address.
        phone:
          type: string
          description: Candidate's phone number.
        currentJobTitle:
          type: string
          description: Current job title.
        currentCompany:
          type: string
          description: Current company name.
        city:
          type: string
          description: City location.
        country:
          type: string
          description: Country.
        skills:
          description: |
            Candidate skills. Documented and observed responses return an
            array of skill strings; the plain-string variant is inferred from
            the input-side CSV coercion and is not verified against
            production behavior.
          x-inferred: true
          oneOf:
            - type: array
              items:
                type: string
            - type: string
        resume:
          type: string
          description: URL to the stored resume file.
        coverLetter:
          type: string
          description: Cover letter text.
        majors:
          type: array
          description: |
            Array of majors/fields of study. Note: submitted as a
            comma-separated string on input, returned as an array of strings.
          items:
            type: string
        summary:
          type: string
          description: Professional summary.
        languages:
          type: array
          description: Array of languages.
          items:
            type: string
        educations:
          type: array
          description: Array of education objects.
          items:
            $ref: '#/components/schemas/CandidateEducation'
        workExperiences:
          type: array
          description: Array of work experience objects.
          items:
            $ref: '#/components/schemas/CandidateWorkExperience'
        projectExperiences:
          type: array
          description: Array of project experience objects.
          items:
            $ref: '#/components/schemas/CandidateProjectExperience'
        certifications:
          type: array
          description: Array of certification objects.
          items:
            $ref: '#/components/schemas/CandidateCertification'
        githubUrl:
          type: string
          description: GitHub profile URL.
        linkedin:
          type: string
          description: LinkedIn profile URL.
        gender:
          type: string
          description: Gender.
        dateOfBirth:
          type: string
          format: date
          description: Date of birth.
        nationality:
          type: string
          description: Nationality.
        industry:
          type: string
          description: Industry.
        category:
          type: string
          description: Category.
    ApiErrorBody:
      type: object
      description: Canonical error object carried under the `error` key.
      required:
        - code
        - type
        - message
      properties:
        code:
          type: string
          description: Machine-readable error code, e.g. `INVALID_REQUEST`.
          examples:
            - INVALID_REQUEST
        type:
          type: string
          description: Error category.
          enum:
            - validation_error
            - internal_error
            - not_found
            - authorization_error
            - resource_error
            - payment_error
            - subscription_error
        message:
          type: string
          description: Human-readable error message.
        details:
          type: object
          description: Optional per-field validation messages or structured error context.
          additionalProperties: true
    AuthMessageError:
      type: object
      description: >-
        Flat authentication error shape (does not use the canonical `error`
        envelope).
      required:
        - message
      properties:
        message:
          type: string
          examples:
            - Invalid API key
    AuthCodeMessageError:
      type: object
      description: >-
        Flat authentication error shape returned when the account subscription
        is inactive.
      required:
        - code
        - message
      properties:
        code:
          type: string
          examples:
            - ACCOUNT_INACTIVE
        message:
          type: string
          examples:
            - >-
              Your subscription is inactive. Please renew your plan to continue
              using this feature.
    AuthApiKeyError:
      type: object
      description: >-
        Flat authentication error shape returned when the API key does not
        exist.
      required:
        - message
        - isApiKeyExists
      properties:
        message:
          type: string
          examples:
            - API key not found
        isApiKeyExists:
          type: boolean
    CandidateEducation:
      type: object
      description: |
        Education object as returned in detailed candidate responses. Differs
        from the request-side `CandidateEducationInput` shape.
      properties:
        degree:
          type: string
          description: Degree name.
        field:
          type: string
          description: Field of study.
        institution:
          type: string
          description: Institution name.
        startDate:
          type: string
          format: date
          description: Start date.
        endDate:
          type: string
          format: date
          description: End date.
    CandidateWorkExperience:
      type: object
      description: |
        Work experience object as returned in detailed candidate responses.
        Differs from the request-side `CandidateWorkExperienceInput` shape.
      properties:
        title:
          type: string
          description: Job title.
        company:
          type: string
          description: Company name.
        location:
          type: string
          description: Work location.
        startDate:
          type: string
          format: date
          description: Start date.
        endDate:
          type:
            - string
            - 'null'
          format: date
          description: End date. `null` for current positions.
        description:
          type: string
          description: Role description.
    CandidateProjectExperience:
      type: object
      description: |
        Project experience object as returned in candidate responses. Differs
        from the request-side `CandidateProjectExperienceInput` shape.
      properties:
        name:
          type: string
          description: Project name.
        description:
          type: string
          description: Project description.
        technologies:
          type: array
          description: Technologies used.
          items:
            type: string
    CandidateCertification:
      type: object
      description: |
        Certification object as returned in candidate responses. Differs from
        the request-side `CandidateCertificationInput` shape.
      properties:
        name:
          type: string
          description: Certification name.
        issuer:
          type: string
          description: Certification issuer.
        issueDate:
          type: string
          format: date
          description: Issue date.
        expiryDate:
          type: string
          format: date
          description: Expiry date.
  responses:
    Unauthorized:
      description: |
        Authentication failed. Note that authentication errors use flat body
        shapes rather than the canonical `error` envelope.
      content:
        application/json:
          schema:
            anyOf:
              - $ref: '#/components/schemas/AuthMessageError'
              - $ref: '#/components/schemas/AuthCodeMessageError'
              - $ref: '#/components/schemas/AuthApiKeyError'
          examples:
            invalidApiKey:
              summary: Invalid API key
              value:
                message: Invalid API key
            accountInactive:
              summary: Subscription inactive
              value:
                code: ACCOUNT_INACTIVE
                message: >-
                  Your subscription is inactive. Please renew your plan to
                  continue using this feature.
            apiKeyNotFound:
              summary: API key not found
              value:
                message: API key not found
                isApiKeyExists: false
    TooManyRequests:
      x-inferred: true
      description: |
        Rate limit exceeded. Rate limits are applied at the company level; the
        response body below is inferred because the current documentation
        mentions handling 429 responses but does not publish a body. Retry
        with exponential backoff.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          examples:
            rateLimited:
              summary: Rate limit exceeded (inferred example)
              value:
                error:
                  code: RATE_LIMIT_EXCEEDED
                  type: validation_error
                  message: Too many requests. Please retry with exponential backoff.
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          examples:
            internalError:
              summary: Internal error
              value:
                error:
                  code: INTERNAL_ERROR
                  type: internal_error
                  message: Something went wrong.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: |
        Company-scoped API key. Production keys are prefixed `sk_live_`,
        sandbox keys `sk_test_`, each followed by 22 base62 characters
        (pattern `^sk_(live|test)_[0-9A-Za-z]{22}$`). Generate keys in the
        TapTalent dashboard under Account Settings → Developers → API Key
        Management; a key is shown once at generation and old keys are
        invalidated immediately on regeneration.

````