{
  "openapi": "3.1.0",
  "info": {
    "title": "Talent-Ray API",
    "version": "2026-06-05",
    "summary": "Programmatic access to the Talent-Ray hiring platform.",
    "description": "The Talent-Ray API lets backend systems and AI agents authenticate with an API key and call platform endpoints. An API key inherits the permissions of the user it was minted for (its ceiling), and may additionally be granted **per-key scopes** that gate the versioned `/api/v1/*` endpoints. A scope never grants access the owner lacks — it only narrows. A key with no scopes authenticates but cannot call scope-gated `/api/v1` endpoints. The stable, curated `/api/v1/*` surface returns versioned response shapes (additive changes only). All requests are HTTPS; all timestamps are ISO 8601 in UTC.",
    "contact": {
      "name": "Talent-Ray",
      "url": "https://talent-ray.com/contact/"
    }
  },
  "servers": [
    {
      "url": "https://{instance}.talent-ray.com",
      "description": "Your Talent-Ray instance. The shared platform is `app.talent-ray.com`. Customers with a dedicated deployment call their own subdomain (e.g. `acme.talent-ray.com`).",
      "variables": {
        "instance": {
          "default": "app",
          "description": "Subdomain of your Talent-Ray instance: `app` for the shared platform, or your dedicated subdomain for a customer-dedicated deployment."
        }
      }
    }
  ],
  "security": [
    {
      "bearerApiKey": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "API Keys",
      "description": "Mint, list, revoke, and audit API keys. These endpoints require an admin-role caller."
    },
    {
      "name": "Career Portal",
      "description": "Public, unauthenticated endpoints that power an organization's candidate-facing career portal."
    },
    {
      "name": "Identity",
      "description": "Resolve the authenticated principal and, for API-key callers, the key id + granted scopes. Part of the stable /api/v1 surface."
    },
    {
      "name": "Candidates",
      "description": "Stable /api/v1 candidate reads + curated updates. Scopes: candidates:read / candidates:write. Visibility is organization-membership based."
    },
    {
      "name": "Roles",
      "description": "Stable /api/v1 role (job) reads + curated updates. Scopes: roles:read / roles:write."
    },
    {
      "name": "Tests",
      "description": "Stable /api/v1 assessment-test reads + curated metadata updates. Scopes: tests:read / tests:write."
    },
    {
      "name": "Sourcing",
      "description": "Stable /api/v1 potential-candidate (sourced lead) CRUD. Scopes: sourcing:read / sourcing:write."
    },
    {
      "name": "Pipeline",
      "description": "Stable /api/v1 pipeline reads: a role's step template and a candidate's step progress. Scope: pipeline:read."
    },
    {
      "name": "CV Screening",
      "description": "Stable /api/v1 CV-screening batch status + results. Scope: cv-screening:read."
    }
  ],
  "paths": {
    "/api/admin/api-keys": {
      "get": {
        "operationId": "listApiKeys",
        "summary": "List API keys",
        "description": "Returns all API keys with owner and usage metadata. The full secret is never returned after creation — only the `start` prefix for display.",
        "tags": [
          "API Keys"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of API keys.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKeySummary"
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "apikey_xyz789",
                      "name": "Karaca SAP nightly sync",
                      "prefix": "tr_",
                      "start": "tr_aaaa",
                      "enabled": true,
                      "createdAt": "2026-06-04T10:00:00Z",
                      "updatedAt": "2026-06-04T10:00:00Z",
                      "lastRequest": "2026-06-04T15:30:45Z",
                      "expiresAt": "2026-09-03T12:00:00Z",
                      "requestCount": 1250,
                      "owner": {
                        "id": "user_abc123",
                        "email": "admin@company.com",
                        "name": "Admin User",
                        "platformRole": "admin",
                        "orgRole": null,
                        "organizationId": null
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createApiKey",
        "summary": "Create an API key",
        "description": "Mints a new API key on behalf of a user. The plaintext `key` is returned EXACTLY ONCE in this response and is never retrievable again — store it securely. The key inherits the target user's role and organization memberships.",
        "tags": [
          "API Keys"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "userId"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Human-readable label for the key.",
                    "example": "Karaca SAP nightly sync"
                  },
                  "userId": {
                    "type": "string",
                    "description": "ID of the user the key acts as. Must exist.",
                    "example": "user_abc123"
                  },
                  "expiresInDays": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 365,
                    "default": 90,
                    "description": "Days until the key expires.",
                    "example": 30
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ApiScope"
                    },
                    "description": "Optional per-key scopes gating the `/api/v1/*` endpoints. Validated against the taxonomy (400 on an unknown scope). Omit for a key with no scopes (it authenticates but cannot call scope-gated `/api/v1` endpoints). Scopes never exceed the owner's role/org access.",
                    "example": [
                      "candidates:read",
                      "roles:read"
                    ]
                  }
                }
              },
              "example": {
                "name": "Karaca SAP nightly sync",
                "userId": "user_abc123",
                "expiresInDays": 30,
                "scopes": [
                  "candidates:read",
                  "roles:read"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Key created. `key` is shown only once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/ApiKeyCreated"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "apikey_xyz789",
                    "name": "Karaca SAP nightly sync",
                    "key": "tr_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "prefix": "tr_",
                    "start": "tr_aaaa",
                    "expiresAt": "2026-09-03T12:00:00Z",
                    "userId": "user_abc123"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingName": {
                    "value": {
                      "error": "Name is required"
                    }
                  },
                  "missingUser": {
                    "value": {
                      "error": "userId is required"
                    }
                  },
                  "badExpiry": {
                    "value": {
                      "error": "expiresInDays must be between 1 and 365"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "Target user not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Target user not found"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/admin/api-keys/{id}": {
      "delete": {
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key",
        "description": "Permanently revokes the key. Subsequent requests using it are rejected.",
        "tags": [
          "API Keys"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The API key ID.",
            "example": "apikey_xyz789"
          }
        ],
        "responses": {
          "200": {
            "description": "Key revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "Key not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Key not found"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/admin/api-keys/{id}/usage": {
      "get": {
        "operationId": "getApiKeyUsage",
        "summary": "Get API key usage log",
        "description": "Returns a cursor-paginated forensic log of requests made with the key. Page backwards in time using `before` set to the previous page's `nextBefore`.",
        "tags": [
          "API Keys"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The API key ID.",
            "example": "apikey_xyz789"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "description": "Rows per page.",
            "example": 50
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 cursor — return rows older than this timestamp.",
            "example": "2026-06-04T15:30:00Z"
          }
        ],
        "responses": {
          "200": {
            "description": "Usage log page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "required": [
                        "key",
                        "rows",
                        "pagination"
                      ],
                      "properties": {
                        "key": {
                          "$ref": "#/components/schemas/ApiKeyUsageOwner"
                        },
                        "rows": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/UsageRow"
                          }
                        },
                        "pagination": {
                          "$ref": "#/components/schemas/CursorPagination"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "key": {
                      "id": "apikey_xyz789",
                      "name": "Karaca SAP nightly sync",
                      "createdAt": "2026-06-04T10:00:00Z",
                      "lastRequest": "2026-06-04T15:30:45Z",
                      "requestCount": 1250,
                      "owner": {
                        "id": "user_abc123",
                        "email": "admin@company.com",
                        "name": "Admin User"
                      }
                    },
                    "rows": [
                      {
                        "id": "usage_001",
                        "timestamp": "2026-06-04T15:30:45Z",
                        "method": "POST",
                        "path": "/api/admin/api-keys",
                        "ip": "192.0.2.100",
                        "userAgent": "curl/7.68.0",
                        "authEndpoint": "/get-session"
                      }
                    ],
                    "pagination": {
                      "limit": 50,
                      "hasMore": true,
                      "nextBefore": "2026-06-04T15:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "Key not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Key not found"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/public/portal/{orgSlug}": {
      "get": {
        "operationId": "getCareerPortal",
        "summary": "Get a public career portal",
        "description": "Returns an organization's public career portal: its branding/theme and all open, public roles. No authentication required. Salary fields on roles are omitted unless the org enables salary display.",
        "tags": [
          "Career Portal"
        ],
        "security": [],
        "parameters": [
          {
            "name": "orgSlug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The organization's portal slug.",
            "example": "acme"
          }
        ],
        "responses": {
          "200": {
            "description": "Career portal data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "org",
                    "roles"
                  ],
                  "properties": {
                    "org": {
                      "$ref": "#/components/schemas/PortalOrg"
                    },
                    "roles": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PortalRole"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Portal not found or not enabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Career portal not found or not enabled"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Failed to fetch career portal data"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/portal/{orgSlug}/roles/{roleId}": {
      "get": {
        "operationId": "getCareerPortalJob",
        "summary": "Get a public job",
        "description": "Returns a single public, open role with its organization metadata. No authentication required.",
        "tags": [
          "Career Portal"
        ],
        "security": [],
        "parameters": [
          {
            "name": "orgSlug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The organization's portal slug.",
            "example": "acme"
          },
          {
            "name": "roleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The role ID.",
            "example": "clx123abc"
          }
        ],
        "responses": {
          "200": {
            "description": "Job detail.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "org",
                    "role"
                  ],
                  "properties": {
                    "org": {
                      "$ref": "#/components/schemas/PortalOrg"
                    },
                    "role": {
                      "$ref": "#/components/schemas/PortalRole"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Portal not found/enabled, or job not found / no longer available.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Job not found or no longer available"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Failed to fetch job details"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/portal/{orgSlug}/apply": {
      "post": {
        "operationId": "applyToCareerPortalJob",
        "summary": "Apply to a public job",
        "description": "Generates (or reuses) a candidate signup invitation link for a public, open role and returns its URL. No authentication required.",
        "tags": [
          "Career Portal"
        ],
        "security": [],
        "parameters": [
          {
            "name": "orgSlug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The organization's portal slug.",
            "example": "acme"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "roleId"
                ],
                "properties": {
                  "roleId": {
                    "type": "string",
                    "description": "The public role to apply for.",
                    "example": "clx123abc"
                  },
                  "locale": {
                    "type": "string",
                    "default": "en",
                    "description": "Language for the generated signup invite link.",
                    "example": "en"
                  }
                }
              },
              "example": {
                "roleId": "clx123abc",
                "locale": "en"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A candidate signup invite link.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "inviteUrl"
                  ],
                  "properties": {
                    "inviteUrl": {
                      "type": "string",
                      "description": "Full signup URL to share with the candidate.",
                      "example": "https://app.talent-ray.com/en/signup/invite/inv_abc123"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing roleId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "roleId is required"
                }
              }
            }
          },
          "404": {
            "description": "Portal not enabled, or job not found / not accepting applications.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Job not found or no longer accepting applications"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Failed to process application"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "operationId": "getMeV1",
        "summary": "Get the authenticated principal",
        "description": "Returns the authenticated user and, for API-key callers, the key id and its granted scopes. Works for both API-key and session callers. The reference endpoint for verifying auth + scope plumbing.",
        "tags": [
          "Identity"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "The authenticated principal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeV1"
                },
                "example": {
                  "user": {
                    "id": "user_abc123",
                    "email": "integrations@acme.com",
                    "role": "user"
                  },
                  "auth": {
                    "type": "api_key",
                    "keyId": "apikey_xyz789",
                    "scopes": [
                      "candidates:read",
                      "roles:read"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/candidates": {
      "get": {
        "operationId": "listCandidatesV1",
        "summary": "List candidates",
        "description": "Lists candidates in a stable, curated shape. Scope: `candidates:read`. Visibility is organization-membership based — admins see all; employer-write members see their org's candidates; hiring managers see candidates in roles assigned to them.",
        "tags": [
          "Candidates"
        ],
        "x-required-scopes": [
          "candidates:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "roleId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to candidates actively assigned to this role.",
            "example": "role_eng_be"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of candidates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CandidateV1"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "cand_1",
                      "fullName": "Jane Doe",
                      "email": "jane@example.com",
                      "phone": "+905551112233",
                      "status": "Active",
                      "createdAt": "2026-06-01T10:00:00Z",
                      "updatedAt": "2026-06-02T08:00:00Z",
                      "roles": [
                        {
                          "roleId": "role_eng_be",
                          "roleName": "Senior Backend Engineer",
                          "organizationId": "org_acme",
                          "status": "In Pipeline",
                          "overallFitScore": 82,
                          "approved": false
                        }
                      ]
                    }
                  ],
                  "pagination": {
                    "page": 0,
                    "pageSize": 20,
                    "totalCount": 134,
                    "totalPages": 7
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/candidates/{id}": {
      "get": {
        "operationId": "getCandidateV1",
        "summary": "Get a candidate",
        "description": "Fetches one candidate in the curated shape. Scope: `candidates:read`. A candidate the caller cannot see returns 404 (no existence leak).",
        "tags": [
          "Candidates"
        ],
        "x-required-scopes": [
          "candidates:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/CandidateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The candidate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CandidateV1"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateCandidateV1",
        "summary": "Update a candidate",
        "description": "Updates a curated set of candidate fields. Scope: `candidates:write`. Requires employer-write authority in one of the candidate's organizations (admins bypass; hiring managers are read-only). Only the whitelisted fields below may be set; unknown fields are ignored and wrong-typed fields return 400.",
        "tags": [
          "Candidates"
        ],
        "x-required-scopes": [
          "candidates:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/CandidateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CandidateUpdateV1"
              },
              "example": {
                "status": "Active",
                "phone": "+905551112233",
                "summary": "Strong backend profile."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated candidate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CandidateV1"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestV1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/candidates/{id}/steps": {
      "get": {
        "operationId": "getCandidateStepsV1",
        "summary": "Get a candidate's pipeline progress",
        "description": "Returns the candidate's step progress across all their roles (CandidateRoleStep), ordered by role then step order. Scope: `pipeline:read`. The parent candidate must be visible (else 404). Not paginated — inherently small and ordered.",
        "tags": [
          "Pipeline"
        ],
        "x-required-scopes": [
          "pipeline:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/CandidateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The candidate's step progress.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CandidateStepV1"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "crs_1",
                      "roleId": "role_eng_be",
                      "roleStepId": "step_cv",
                      "name": "CV Screening",
                      "order": 1,
                      "stepType": "cv_screening",
                      "status": "validated",
                      "startedAt": "2026-06-01T10:00:00Z",
                      "completedAt": "2026-06-01T11:00:00Z",
                      "validatedAt": "2026-06-01T11:05:00Z",
                      "rejectedAt": null,
                      "validationScore": 78,
                      "rejectionReason": null,
                      "offerResponse": null,
                      "createdAt": "2026-06-01T10:00:00Z",
                      "updatedAt": "2026-06-01T11:05:00Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/roles": {
      "get": {
        "operationId": "listRolesV1",
        "summary": "List roles",
        "description": "Lists roles (jobs) in a stable, curated shape. Scope: `roles:read`. Visibility: admins all; employer-write members see their org's roles (confidential roles only if HR rep / hiring manager); hiring managers see assigned roles.",
        "tags": [
          "Roles"
        ],
        "x-required-scopes": [
          "roles:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "organizationId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single organization.",
            "example": "org_acme"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by role status.",
            "example": "open"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of roles.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RoleV1"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "role_eng_be",
                      "name": "Senior Backend Engineer",
                      "organizationId": "org_acme",
                      "status": "open",
                      "priority": "high",
                      "isPublic": true,
                      "department": "Engineering",
                      "location": "Remote",
                      "workType": "remote",
                      "salaryMin": 90000,
                      "salaryMax": 120000,
                      "salaryCurrency": "EUR",
                      "salaryPeriod": "year",
                      "targetHireCount": 2,
                      "roleLevel": "senior",
                      "createdAt": "2026-05-01T09:00:00Z",
                      "updatedAt": "2026-06-01T09:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 0,
                    "pageSize": 20,
                    "totalCount": 12,
                    "totalPages": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/roles/{id}": {
      "get": {
        "operationId": "getRoleV1",
        "summary": "Get a role",
        "description": "Fetches one role in the curated shape. Scope: `roles:read`. A role the caller cannot see returns 404 (no existence leak).",
        "tags": [
          "Roles"
        ],
        "x-required-scopes": [
          "roles:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RoleId"
          }
        ],
        "responses": {
          "200": {
            "description": "The role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleV1"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateRoleV1",
        "summary": "Update a role",
        "description": "Updates a curated set of role fields. Scope: `roles:write`. Requires employer-write authority in the role's org (admins bypass). Excludes pipeline/structure/confidentiality fields. Unknown fields are ignored; wrong-typed fields return 400.",
        "tags": [
          "Roles"
        ],
        "x-required-scopes": [
          "roles:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RoleId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleUpdateV1"
              },
              "example": {
                "status": "open",
                "priority": "high",
                "location": "Istanbul",
                "salaryMax": 130000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleV1"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestV1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/roles/{id}/steps": {
      "get": {
        "operationId": "getRoleStepsV1",
        "summary": "Get a role's pipeline template",
        "description": "Returns the role's ordered pipeline steps (RoleStep template). Scope: `pipeline:read`. The parent role must be visible (else 404). Not paginated — inherently small and ordered.",
        "tags": [
          "Pipeline"
        ],
        "x-required-scopes": [
          "pipeline:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RoleId"
          }
        ],
        "responses": {
          "200": {
            "description": "The role's step template.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RoleStepV1"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "step_cv",
                      "roleId": "role_eng_be",
                      "name": "CV Screening",
                      "description": null,
                      "order": 1,
                      "stepType": "cv_screening",
                      "validationType": "auto",
                      "passingScore": 70,
                      "isRequired": true,
                      "allowSkip": false,
                      "createdAt": "2026-05-01T09:00:00Z",
                      "updatedAt": "2026-05-01T09:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/tests": {
      "get": {
        "operationId": "listTestsV1",
        "summary": "List tests",
        "description": "Lists assessment tests in a stable, curated shape (excludes the question `content`). Scope: `tests:read`. Visibility: admins all; everyone else sees their org's tests plus platform-global (public) tests.",
        "tags": [
          "Tests"
        ],
        "x-required-scopes": [
          "tests:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by test type.",
            "example": "multiple_choice"
          },
          {
            "name": "analysisCategory",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by analysis category.",
            "example": "hard_skill"
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by language (ISO 639-1).",
            "example": "en"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of tests.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TestV1"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "test_js",
                      "name": "JavaScript Fundamentals",
                      "type": "multiple_choice",
                      "description": "Core JS assessment.",
                      "duration": 30,
                      "targetPersona": "Backend Engineer",
                      "analysisCategory": "hard_skill",
                      "language": "en",
                      "isPublic": false,
                      "organizationIds": [
                        "org_acme"
                      ],
                      "createdAt": "2026-04-01T09:00:00Z",
                      "updatedAt": "2026-04-10T09:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 0,
                    "pageSize": 20,
                    "totalCount": 48,
                    "totalPages": 3
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/tests/{id}": {
      "get": {
        "operationId": "getTestV1",
        "summary": "Get a test",
        "description": "Fetches one test in the curated shape (excludes `content`). Scope: `tests:read`. A test the caller cannot see returns 404.",
        "tags": [
          "Tests"
        ],
        "x-required-scopes": [
          "tests:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TestId"
          }
        ],
        "responses": {
          "200": {
            "description": "The test.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestV1"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateTestV1",
        "summary": "Update a test",
        "description": "Updates curated test metadata (not the question `content`). Scope: `tests:write`. Requires employer-write authority in one of the test's organizations (admins bypass; platform-global tests with no org are admin-only).",
        "tags": [
          "Tests"
        ],
        "x-required-scopes": [
          "tests:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TestId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestUpdateV1"
              },
              "example": {
                "name": "JavaScript Fundamentals (2026)",
                "duration": 35,
                "targetPersona": "Backend Engineer"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated test.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestV1"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestV1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/sourcing": {
      "get": {
        "operationId": "listSourcingV1",
        "summary": "List potential candidates",
        "description": "Lists potential candidates (sourced/CV-screened leads) in a stable, curated shape. Scope: `sourcing:read`. Visibility: admins all; everyone else sees leads linked to an org they belong to.",
        "tags": [
          "Sourcing"
        ],
        "x-required-scopes": [
          "sourcing:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "roleId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to leads linked to this role.",
            "example": "role_eng_be"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by lead status.",
            "example": "parsed"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of potential candidates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SourcingV1"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "pc_1",
                      "fullName": "Sam Lee",
                      "email": "sam.cv@example.com",
                      "contactEmail": "sam@example.com",
                      "phone": "+905559998877",
                      "status": "parsed",
                      "skills": [
                        "python",
                        "sql"
                      ],
                      "summary": "5y data engineering.",
                      "candidateId": null,
                      "organizations": [
                        {
                          "organizationId": "org_acme",
                          "status": "Pool"
                        }
                      ],
                      "roles": [
                        {
                          "roleId": "role_eng_be",
                          "roleName": "Senior Backend Engineer",
                          "organizationId": "org_acme",
                          "status": "Assigned",
                          "resumeFitScore": 71,
                          "overallFitScore": -1
                        }
                      ],
                      "createdAt": "2026-06-01T10:00:00Z",
                      "updatedAt": "2026-06-01T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 0,
                    "pageSize": 20,
                    "totalCount": 60,
                    "totalPages": 3
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createSourcingV1",
        "summary": "Create a potential candidate",
        "description": "Creates a potential candidate (lead) in a target organization. Scope: `sourcing:write`. Requires employer-write authority in `organizationId` (admins bypass) and that the org exists. Links the organization membership row.",
        "tags": [
          "Sourcing"
        ],
        "x-required-scopes": [
          "sourcing:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SourcingCreateV1"
              },
              "example": {
                "fullName": "Sam Lee",
                "organizationId": "org_acme",
                "contactEmail": "sam@example.com",
                "skills": [
                  "python",
                  "sql"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created potential candidate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourcingV1"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestV1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/sourcing/{id}": {
      "get": {
        "operationId": "getSourcingV1",
        "summary": "Get a potential candidate",
        "description": "Fetches one potential candidate in the curated shape. Scope: `sourcing:read`. A lead the caller cannot see returns 404.",
        "tags": [
          "Sourcing"
        ],
        "x-required-scopes": [
          "sourcing:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SourcingId"
          }
        ],
        "responses": {
          "200": {
            "description": "The potential candidate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourcingV1"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateSourcingV1",
        "summary": "Update a potential candidate",
        "description": "Updates a curated set of potential-candidate fields. Scope: `sourcing:write`. Requires employer-write authority in one of the lead's organizations (admins bypass).",
        "tags": [
          "Sourcing"
        ],
        "x-required-scopes": [
          "sourcing:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SourcingId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SourcingUpdateV1"
              },
              "example": {
                "status": "parsed",
                "skills": [
                  "python",
                  "sql",
                  "airflow"
                ],
                "summary": "Updated profile."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated potential candidate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourcingV1"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestV1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deleteSourcingV1",
        "summary": "Delete a potential candidate",
        "description": "Permanently deletes a potential candidate (cascade removes its role/org links). Scope: `sourcing:write`. Requires employer-write authority in one of the lead's organizations (admins bypass). Writes a role-activity audit entry per active role.",
        "tags": [
          "Sourcing"
        ],
        "x-required-scopes": [
          "sourcing:write"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SourcingId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. No content."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScopeOrForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/cv-screening/batches/{batchId}": {
      "get": {
        "operationId": "getCvScreeningBatchV1",
        "summary": "Get a CV-screening batch",
        "description": "Returns a CV-screening batch's processing status plus its per-member results (reusing the potential-candidate shape). Scope: `cv-screening:read`. Only batch members linked to an org the caller belongs to are counted/returned; a batch with no visible members returns 404.",
        "tags": [
          "CV Screening"
        ],
        "x-required-scopes": [
          "cv-screening:read"
        ],
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "batchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The CV-screening batch id.",
            "example": "batch_2026_06_01"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch status + a page of members.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CvScreeningBatchV1"
                },
                "example": {
                  "batchId": "batch_2026_06_01",
                  "status": "completed",
                  "totalCandidates": 25,
                  "completedCandidates": 25,
                  "processingCandidates": 0,
                  "data": [
                    {
                      "id": "pc_1",
                      "fullName": "Sam Lee",
                      "email": "sam.cv@example.com",
                      "contactEmail": null,
                      "phone": null,
                      "status": "parsed",
                      "skills": [
                        "python"
                      ],
                      "summary": null,
                      "candidateId": null,
                      "organizations": [
                        {
                          "organizationId": "org_acme",
                          "status": "Pool"
                        }
                      ],
                      "roles": [],
                      "createdAt": "2026-06-01T10:00:00Z",
                      "updatedAt": "2026-06-01T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 0,
                    "pageSize": 20,
                    "totalCount": 25,
                    "totalPages": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundV1"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Talent-Ray API key (tr_ prefix, 67 chars)",
        "description": "Send the key as `Authorization: Bearer tr_...`. Preferred transport."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Send the key as `x-api-key: tr_...`. Accepted fallback for the Bearer header."
      }
    },
    "parameters": {
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        },
        "description": "0-indexed page number.",
        "example": 0
      },
      "PageSize": {
        "name": "pageSize",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        },
        "description": "Rows per page (max 100).",
        "example": 20
      },
      "CandidateId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "The candidate id.",
        "example": "cand_1"
      },
      "RoleId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "The role id.",
        "example": "role_eng_be"
      },
      "TestId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "The test id.",
        "example": "test_js"
      },
      "SourcingId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "The potential-candidate id.",
        "example": "pc_1"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "No valid API key was supplied.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Unauthorized"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The key's owner lacks the required role for this endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Forbidden - Admin access required"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Per-key rate limit exceeded (default 600 requests/minute). Honor the `Retry-After` header.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait before retrying."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Too many requests"
            }
          }
        }
      },
      "InsufficientScope": {
        "description": "The API key is missing a required scope for this `/api/v1` endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ScopeError"
            },
            "example": {
              "error": "insufficient_scope",
              "message": "This API key is missing required scope(s): candidates:read.",
              "requiredScopes": [
                "candidates:read"
              ],
              "grantedScopes": [
                "roles:read"
              ]
            }
          }
        }
      },
      "InsufficientScopeOrForbidden": {
        "description": "The API key is missing the required scope (`insufficient_scope`), or the caller lacks employer-write authority in the resource's organization (`forbidden`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/V1Error"
            },
            "examples": {
              "insufficientScope": {
                "value": {
                  "error": "insufficient_scope",
                  "message": "This API key is missing required scope(s): candidates:write.",
                  "requiredScopes": [
                    "candidates:write"
                  ],
                  "grantedScopes": []
                }
              },
              "forbidden": {
                "value": {
                  "error": "forbidden"
                }
              }
            }
          }
        }
      },
      "BadRequestV1": {
        "description": "Invalid request body or field(s).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/V1Error"
            },
            "examples": {
              "invalidField": {
                "value": {
                  "error": "bad_request",
                  "message": "Invalid field(s)",
                  "details": [
                    "status must be a non-empty string"
                  ]
                }
              },
              "noFields": {
                "value": {
                  "error": "bad_request",
                  "message": "No updatable fields provided"
                }
              }
            }
          }
        }
      },
      "NotFoundV1": {
        "description": "The resource does not exist, or the caller may not see it (no existence leak).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/V1Error"
            },
            "example": {
              "error": "not_found"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        }
      },
      "ApiKeyOwner": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "user_abc123"
          },
          "email": {
            "type": "string",
            "format": "email",
            "example": "admin@company.com"
          },
          "name": {
            "type": "string",
            "example": "Admin User"
          },
          "platformRole": {
            "type": [
              "string",
              "null"
            ],
            "example": "admin"
          },
          "orgRole": {
            "type": [
              "string",
              "null"
            ],
            "example": null
          },
          "organizationId": {
            "type": [
              "string",
              "null"
            ],
            "example": null
          }
        }
      },
      "ApiKeySummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "apikey_xyz789"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Karaca SAP nightly sync"
          },
          "prefix": {
            "type": "string",
            "example": "tr_"
          },
          "start": {
            "type": "string",
            "description": "First chars of the key for display.",
            "example": "tr_aaaa"
          },
          "enabled": {
            "type": "boolean",
            "example": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastRequest": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "requestCount": {
            "type": "integer",
            "example": 1250
          },
          "owner": {
            "$ref": "#/components/schemas/ApiKeyOwner"
          }
        }
      },
      "ApiKeyCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "apikey_xyz789"
          },
          "name": {
            "type": "string",
            "example": "Karaca SAP nightly sync"
          },
          "key": {
            "type": "string",
            "description": "PLAINTEXT KEY — shown only once. Store securely.",
            "example": "tr_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          },
          "prefix": {
            "type": "string",
            "example": "tr_"
          },
          "start": {
            "type": "string",
            "example": "tr_aaaa"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-03T12:00:00Z"
          },
          "userId": {
            "type": "string",
            "example": "user_abc123"
          }
        }
      },
      "ApiKeyUsageOwner": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "apikey_xyz789"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Karaca SAP nightly sync"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastRequest": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "requestCount": {
            "type": "integer",
            "example": 1250
          },
          "owner": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "user_abc123"
              },
              "email": {
                "type": "string",
                "format": "email",
                "example": "admin@company.com"
              },
              "name": {
                "type": "string",
                "example": "Admin User"
              }
            }
          }
        }
      },
      "UsageRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "usage_001"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "example": "2026-06-04T15:30:45Z"
          },
          "method": {
            "type": "string",
            "example": "POST"
          },
          "path": {
            "type": "string",
            "example": "/api/admin/api-keys"
          },
          "ip": {
            "type": "string",
            "example": "192.0.2.100"
          },
          "userAgent": {
            "type": "string",
            "example": "curl/7.68.0"
          },
          "authEndpoint": {
            "type": "string",
            "example": "/get-session"
          }
        }
      },
      "CursorPagination": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "example": 50
          },
          "hasMore": {
            "type": "boolean",
            "example": true
          },
          "nextBefore": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Pass as `before` to fetch the next (older) page. Null when no more rows.",
            "example": "2026-06-04T15:20:00Z"
          }
        }
      },
      "PortalTheme": {
        "type": "object",
        "description": "Branding/theme for the career portal.",
        "properties": {
          "primaryColor": {
            "type": "string"
          },
          "accentColor": {
            "type": "string"
          },
          "fontFamily": {
            "type": "string"
          },
          "heroTitle": {
            "type": "string"
          },
          "heroDescription": {
            "type": "string"
          },
          "heroImageUrl": {
            "type": "string"
          },
          "showSalary": {
            "type": "boolean",
            "description": "When true, role salary fields are included in responses; otherwise they are omitted."
          }
        }
      },
      "PortalOrg": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Acme Inc."
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          },
          "slug": {
            "type": "string",
            "example": "acme"
          },
          "domain": {
            "type": [
              "string",
              "null"
            ]
          },
          "portalTheme": {
            "$ref": "#/components/schemas/PortalTheme"
          }
        }
      },
      "PortalRole": {
        "type": "object",
        "description": "A public role. Salary fields are present only when the org's portalTheme.showSalary is true.",
        "properties": {
          "id": {
            "type": "string",
            "example": "clx123abc"
          },
          "name": {
            "type": "string",
            "example": "Senior Backend Engineer"
          },
          "description": {
            "description": "Structured job description content (JSON)."
          },
          "department": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "workType": {
            "type": [
              "string",
              "null"
            ],
            "description": "remote | hybrid | onsite"
          },
          "collarType": {
            "type": [
              "string",
              "null"
            ],
            "description": "white | gray | blue"
          },
          "salaryMin": {
            "type": [
              "number",
              "null"
            ],
            "description": "Omitted unless portalTheme.showSalary is true."
          },
          "salaryMax": {
            "type": [
              "number",
              "null"
            ],
            "description": "Omitted unless portalTheme.showSalary is true."
          },
          "salaryCurrency": {
            "type": [
              "string",
              "null"
            ],
            "description": "Omitted unless portalTheme.showSalary is true."
          },
          "salaryPeriod": {
            "type": [
              "string",
              "null"
            ],
            "description": "Omitted unless portalTheme.showSalary is true."
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          },
          "brand": {
            "type": [
              "string",
              "null"
            ]
          },
          "jobFamily": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "subCategory": {
            "type": [
              "string",
              "null"
            ]
          },
          "workLocation": {
            "type": [
              "string",
              "null"
            ]
          },
          "teamDetail": {
            "type": [
              "string",
              "null"
            ]
          },
          "roleLevel": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApiScope": {
        "type": "string",
        "description": "A per-key scope governing the /api/v1 endpoints.",
        "enum": [
          "candidates:read",
          "candidates:write",
          "roles:read",
          "roles:write",
          "pipeline:read",
          "pipeline:write",
          "tests:read",
          "tests:write",
          "cv-screening:read",
          "cv-screening:write",
          "sourcing:read",
          "sourcing:write"
        ]
      },
      "V1Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "Error envelope for the /api/v1 endpoints.",
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable machine error code (e.g. `bad_request`, `not_found`, `forbidden`, `insufficient_scope`, `internal_error`)."
          },
          "message": {
            "type": "string",
            "description": "Human-readable detail (optional)."
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Field-level validation messages (on 400)."
          },
          "requiredScopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiScope"
            }
          },
          "grantedScopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiScope"
            }
          }
        }
      },
      "ScopeError": {
        "type": "object",
        "required": [
          "error",
          "message",
          "requiredScopes",
          "grantedScopes"
        ],
        "properties": {
          "error": {
            "type": "string",
            "const": "insufficient_scope"
          },
          "message": {
            "type": "string"
          },
          "requiredScopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiScope"
            }
          },
          "grantedScopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiScope"
            }
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "required": [
          "page",
          "pageSize",
          "totalCount",
          "totalPages"
        ],
        "properties": {
          "page": {
            "type": "integer",
            "example": 0
          },
          "pageSize": {
            "type": "integer",
            "example": 20
          },
          "totalCount": {
            "type": "integer",
            "example": 134
          },
          "totalPages": {
            "type": "integer",
            "example": 7
          }
        }
      },
      "MeV1": {
        "type": "object",
        "required": [
          "user",
          "auth"
        ],
        "properties": {
          "user": {
            "type": "object",
            "required": [
              "id",
              "email",
              "role"
            ],
            "properties": {
              "id": {
                "type": "string",
                "example": "user_abc123"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "email",
                "example": "integrations@acme.com"
              },
              "role": {
                "type": "string",
                "description": "Platform role: `admin` or `user`.",
                "example": "user"
              }
            }
          },
          "auth": {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "description": "`api_key` or `session`.",
                "example": "api_key"
              },
              "keyId": {
                "type": "string",
                "description": "Present for api_key callers.",
                "example": "apikey_xyz789"
              },
              "scopes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ApiScope"
                },
                "description": "Granted scopes (api_key callers)."
              }
            }
          }
        }
      },
      "CandidateRoleV1": {
        "type": "object",
        "properties": {
          "roleId": {
            "type": "string",
            "example": "role_eng_be"
          },
          "roleName": {
            "type": [
              "string",
              "null"
            ],
            "example": "Senior Backend Engineer"
          },
          "organizationId": {
            "type": [
              "string",
              "null"
            ],
            "example": "org_acme"
          },
          "status": {
            "type": "string",
            "example": "In Pipeline"
          },
          "overallFitScore": {
            "type": "number",
            "description": "-1 until scored, then 0–100.",
            "example": 82
          },
          "approved": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "CandidateV1": {
        "type": "object",
        "required": [
          "id",
          "fullName",
          "status",
          "createdAt",
          "updatedAt",
          "roles"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "cand_1"
          },
          "fullName": {
            "type": "string",
            "example": "Jane Doe"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "example": "jane@example.com"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "example": "+905551112233"
          },
          "status": {
            "type": "string",
            "example": "Active"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CandidateRoleV1"
            }
          }
        }
      },
      "CandidateUpdateV1": {
        "type": "object",
        "description": "Curated, partial update. Send only the fields to change.",
        "minProperties": 1,
        "properties": {
          "fullName": {
            "type": "string",
            "example": "Jane Doe"
          },
          "status": {
            "type": "string",
            "example": "Active"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "RoleV1": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status",
          "isPublic",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "role_eng_be"
          },
          "name": {
            "type": "string",
            "example": "Senior Backend Engineer"
          },
          "organizationId": {
            "type": [
              "string",
              "null"
            ],
            "example": "org_acme"
          },
          "status": {
            "type": "string",
            "example": "open"
          },
          "priority": {
            "type": [
              "string",
              "null"
            ],
            "example": "high"
          },
          "isPublic": {
            "type": "boolean",
            "example": true
          },
          "department": {
            "type": [
              "string",
              "null"
            ],
            "example": "Engineering"
          },
          "location": {
            "type": [
              "string",
              "null"
            ],
            "example": "Remote"
          },
          "workType": {
            "type": [
              "string",
              "null"
            ],
            "example": "remote"
          },
          "salaryMin": {
            "type": [
              "number",
              "null"
            ],
            "example": 90000
          },
          "salaryMax": {
            "type": [
              "number",
              "null"
            ],
            "example": 120000
          },
          "salaryCurrency": {
            "type": [
              "string",
              "null"
            ],
            "example": "EUR"
          },
          "salaryPeriod": {
            "type": [
              "string",
              "null"
            ],
            "example": "year"
          },
          "targetHireCount": {
            "type": [
              "integer",
              "null"
            ],
            "example": 2
          },
          "roleLevel": {
            "type": [
              "string",
              "null"
            ],
            "example": "senior"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RoleUpdateV1": {
        "type": "object",
        "description": "Curated, partial update. Send only the fields to change.",
        "minProperties": 1,
        "properties": {
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "priority": {
            "type": [
              "string",
              "null"
            ]
          },
          "department": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "workType": {
            "type": [
              "string",
              "null"
            ]
          },
          "salaryCurrency": {
            "type": [
              "string",
              "null"
            ]
          },
          "salaryPeriod": {
            "type": [
              "string",
              "null"
            ]
          },
          "roleLevel": {
            "type": [
              "string",
              "null"
            ]
          },
          "salaryMin": {
            "type": [
              "integer",
              "null"
            ]
          },
          "salaryMax": {
            "type": [
              "integer",
              "null"
            ]
          },
          "targetHireCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "isPublic": {
            "type": "boolean"
          }
        }
      },
      "RoleStepV1": {
        "type": "object",
        "required": [
          "id",
          "roleId",
          "name",
          "order",
          "validationType",
          "isRequired",
          "allowSkip",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "step_cv"
          },
          "roleId": {
            "type": "string",
            "example": "role_eng_be"
          },
          "name": {
            "type": "string",
            "example": "CV Screening"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "order": {
            "type": "integer",
            "description": "1-based step order.",
            "example": 1
          },
          "stepType": {
            "type": [
              "string",
              "null"
            ],
            "description": "cv_screening | ai_assessment | interview | application_form | document_upload | offer | reference_check | contract | custom.",
            "example": "cv_screening"
          },
          "validationType": {
            "type": "string",
            "description": "auto | manual | score_threshold.",
            "example": "auto"
          },
          "passingScore": {
            "type": [
              "number",
              "null"
            ],
            "example": 70
          },
          "isRequired": {
            "type": "boolean",
            "example": true
          },
          "allowSkip": {
            "type": "boolean",
            "example": false
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CandidateStepV1": {
        "type": "object",
        "required": [
          "id",
          "roleId",
          "roleStepId",
          "name",
          "order",
          "status",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "crs_1"
          },
          "roleId": {
            "type": "string",
            "example": "role_eng_be"
          },
          "roleStepId": {
            "type": "string",
            "example": "step_cv"
          },
          "name": {
            "type": "string",
            "example": "CV Screening"
          },
          "order": {
            "type": "integer",
            "example": 1
          },
          "stepType": {
            "type": [
              "string",
              "null"
            ],
            "example": "cv_screening"
          },
          "status": {
            "type": "string",
            "description": "locked | active | completed | validated | rejected | skipped.",
            "example": "validated"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "validatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "rejectedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "validationScore": {
            "type": [
              "number",
              "null"
            ],
            "description": "Aggregate step score (0–100), or null.",
            "example": 78
          },
          "rejectionReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "offerResponse": {
            "type": [
              "string",
              "null"
            ],
            "description": "accepted | declined | null (offer steps only)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TestV1": {
        "type": "object",
        "required": [
          "id",
          "name",
          "type",
          "description",
          "duration",
          "analysisCategory",
          "language",
          "isPublic",
          "organizationIds",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "test_js"
          },
          "name": {
            "type": "string",
            "example": "JavaScript Fundamentals"
          },
          "type": {
            "type": "string",
            "example": "multiple_choice"
          },
          "description": {
            "type": "string",
            "example": "Core JS assessment."
          },
          "duration": {
            "type": "integer",
            "description": "Minutes.",
            "example": 30
          },
          "targetPersona": {
            "type": [
              "string",
              "null"
            ],
            "example": "Backend Engineer"
          },
          "analysisCategory": {
            "type": "string",
            "example": "hard_skill"
          },
          "language": {
            "type": "string",
            "description": "ISO 639-1.",
            "example": "en"
          },
          "isPublic": {
            "type": "boolean",
            "description": "True when the test has no linked organization (platform-global).",
            "example": false
          },
          "organizationIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "org_acme"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TestUpdateV1": {
        "type": "object",
        "description": "Curated, partial update of test metadata (not the question content).",
        "minProperties": 1,
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "analysisCategory": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "targetPersona": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration": {
            "type": "integer"
          }
        }
      },
      "SourcingOrgV1": {
        "type": "object",
        "properties": {
          "organizationId": {
            "type": "string",
            "example": "org_acme"
          },
          "status": {
            "type": "string",
            "description": "Org-level status: Pool | UnderReview | Blocked.",
            "example": "Pool"
          }
        }
      },
      "SourcingRoleV1": {
        "type": "object",
        "properties": {
          "roleId": {
            "type": "string",
            "example": "role_eng_be"
          },
          "roleName": {
            "type": [
              "string",
              "null"
            ],
            "example": "Senior Backend Engineer"
          },
          "organizationId": {
            "type": [
              "string",
              "null"
            ],
            "example": "org_acme"
          },
          "status": {
            "type": "string",
            "example": "Assigned"
          },
          "resumeFitScore": {
            "type": "number",
            "description": "CV fit; -1 until screened, then 0–100.",
            "example": 71
          },
          "overallFitScore": {
            "type": "number",
            "description": "-1 until scored, then 0–100.",
            "example": -1
          }
        }
      },
      "SourcingV1": {
        "type": "object",
        "required": [
          "id",
          "fullName",
          "status",
          "skills",
          "organizations",
          "roles",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "pc_1"
          },
          "fullName": {
            "type": "string",
            "example": "Sam Lee"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email parsed from the CV.",
            "format": "email"
          },
          "contactEmail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Account/contact email for invitations.",
            "format": "email"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "example": "parsed"
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "python",
              "sql"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "candidateId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Set once converted into a Candidate."
          },
          "organizations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourcingOrgV1"
            }
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourcingRoleV1"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SourcingCreateV1": {
        "type": "object",
        "required": [
          "fullName",
          "organizationId"
        ],
        "properties": {
          "fullName": {
            "type": "string",
            "example": "Sam Lee"
          },
          "organizationId": {
            "type": "string",
            "description": "Org to create the lead in; caller must have employer-write authority there.",
            "example": "org_acme"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "contactEmail": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "description": "Defaults to `uploaded`."
          }
        }
      },
      "SourcingUpdateV1": {
        "type": "object",
        "description": "Curated, partial update. Send only the fields to change.",
        "minProperties": 1,
        "properties": {
          "fullName": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "contactEmail": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CvScreeningBatchV1": {
        "type": "object",
        "required": [
          "batchId",
          "status",
          "totalCandidates",
          "completedCandidates",
          "processingCandidates",
          "data",
          "pagination"
        ],
        "properties": {
          "batchId": {
            "type": "string",
            "example": "batch_2026_06_01"
          },
          "status": {
            "type": "string",
            "description": "`processing` while any member is still processing, else `completed`.",
            "example": "completed"
          },
          "totalCandidates": {
            "type": "integer",
            "example": 25
          },
          "completedCandidates": {
            "type": "integer",
            "example": 25
          },
          "processingCandidates": {
            "type": "integer",
            "example": 0
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourcingV1"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      }
    }
  }
}