{"openapi":"3.1.0","info":{"title":"Talentlead API","version":"1.0.0","description":"The Talentlead public API gives ATS and HR systems programmatic access to the platform: import people, invite them to an assessment, and read results and matching data.\n\n## Authentication\n\nAll endpoints require an API key via the `Authorization` header:\n\n```\nAuthorization: Bearer tl_live_...\n```\n\nAPI keys are managed in the Talentlead dashboard under **Organisatie → API** and are available on the Professional and Business plans. Every team member can create keys with their own scopes; keys with the `webhooks:manage` scope require an administrator. Keys carry scopes; each endpoint documents the scope it requires. A `*:write` scope implies the corresponding `*:read` scope.\n\n## Concepts\n\n- **Person** — someone in your talent pool, identified by a UUID. A person may exist without a completed assessment (for example right after an ATS import) and counts toward your plan's person limit. Use `externalId` to store your own system's identifier.\n- **Consent** — a person owns their assessment data. Importing a person never exposes results from assessments they took before joining your organization; that requires the person's own consent via the invitation flow.\n- **Matching** — comparative endpoints (profile matches) expose only the aggregated match percentage and category (low/moderate/high). Individual competency scores are never comparable between persons; per-person endpoints do include the full breakdown.\n\n## Errors\n\nErrors use a flat envelope: `{ \"error\": \"...\", \"code\": \"...\", \"details\": { ... } }`. The `code` field is stable and machine-readable.\n\n## Rate limits\n\nRequests are rate-limited per organization (Professional: 120/min, Business: 600/min) and per API key (Professional: 60/min, Business: 300/min). The `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers on every response reflect whichever budget has the least remaining; a 429 response includes `Retry-After`.","contact":{"name":"Talentlead","url":"https://talentlead.nl"}},"servers":[{"url":"https://assessment.talentlead.nl","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Authentication","description":"Key validation"},{"name":"Organization","description":"Your organization, subscription and usage"},{"name":"Persons","description":"People in your talent pool"},{"name":"Results","description":"Assessment results, matches and reports"},{"name":"Profiles","description":"Competency profiles"},{"name":"Invitations","description":"Personal assessment invitations"},{"name":"Webhooks","description":"Event subscriptions"}],"paths":{"/api/v1/me":{"get":{"tags":["Authentication"],"summary":"Validate your API key","description":"Returns the identity behind the API key: user, organization, granted scopes and plan. Requires no scopes — useful as a connectivity check.","operationId":"getMe","responses":{"200":{"description":"Key is valid","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"organizationId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"organizationRole":{"type":"string","enum":["admin","member"]},"scopes":{"type":"array","items":{"type":"string"}},"plan":{"description":"Current plan id, e.g. professional","type":"string"}},"required":["userId","organizationId","organizationRole","scopes","plan"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/organization":{"get":{"tags":["Organization"],"summary":"Get your organization","description":"Organization details, subscription state and plan usage. Requires the `organization:read` scope.","operationId":"getOrganization","responses":{"200":{"description":"Your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"companyName":{"type":"string"},"email":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"subscription":{"type":"object","properties":{"plan":{"type":"string"},"status":{"type":"string","enum":["trialing","trial_expired","needs_plan","active","past_due","canceled"]},"trialEndsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["plan","status","trialEndsAt","currentPeriodEnd"],"additionalProperties":false},"usage":{"type":"object","properties":{"persons":{"type":"object","properties":{"used":{"type":"number"},"limit":{"type":"number"},"importBlocked":{"description":"true when imports and invitations are blocked (limit or inactive subscription)","type":"boolean"}},"required":["used","limit","importBlocked"],"additionalProperties":false},"profiles":{"type":"object","properties":{"used":{"type":"number"},"limit":{"type":"number"}},"required":["used","limit"],"additionalProperties":false}},"required":["persons","profiles"],"additionalProperties":false}},"required":["id","companyName","email","createdAt","subscription","usage"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/persons":{"get":{"tags":["Persons"],"summary":"List persons","description":"People in your talent pool, newest first, cursor-paginated. Requires the `persons:read` scope.","operationId":"listPersons","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":100},"description":"Case-insensitive substring search across first name, last name and email"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","archived"],"default":"active"}},{"name":"email","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"externalId","in":"query","schema":{"type":"string"},"description":"Exact match on your own identifier"},{"name":"assessmentStatus","in":"query","schema":{"type":"string","enum":["not_started","in_progress","completed"]}},{"name":"label","in":"query","schema":{"type":"string","enum":["candidate","employee","other"]},"description":"Filter by label; \"other\" matches persons without any label"},{"name":"tag","in":"query","schema":{"type":"string"},"description":"Filter by tag name (case-insensitive exact match)"},{"name":"updatedAfter","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only persons changed after this moment — for incremental syncs"},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Cursor from the previous page"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"A page of persons","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"description":"Opaque cursor for the next page; pass as ?cursor=","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false}}}},"400":{"description":"Invalid filter or cursor","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"post":{"tags":["Persons"],"summary":"Import a person","description":"Creates or reactivates a person in your talent pool (ATS sync). The person counts toward your plan's person limit immediately. Idempotent on email: an already-active member returns 200 with `X-Existing-Resource: true`. Optionally creates an assessment invitation in the same call via the nested `invitation` object. Supports the `Idempotency-Key` header. Requires the `persons:write` scope.\n\nA person who withdrew their own participation cannot be reactivated by import (409 `person_self_revoked`); they can only rejoin by accepting a new invitation themselves.","operationId":"importPerson","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"firstName":{"type":"string","minLength":1,"maxLength":100},"lastName":{"type":"string","minLength":1,"maxLength":100},"externalId":{"type":"string","minLength":1,"maxLength":255},"labels":{"description":"Labels for this person within your organization: \"candidate\" and/or \"employee\"; an empty array means neither (\"other\"). Omitted on create: defaults to [\"candidate\"]. The employee email-domain rule can additionally add \"employee\".","maxItems":2,"type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Tags to add (existing tags on the person are kept)","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":50}},"invitation":{"description":"Create an assessment invitation in the same call","type":"object","properties":{"create":{"type":"boolean","const":true},"sendEmail":{"description":"true: Talentlead sends the invitation email; false: you send the returned url yourself","type":"boolean"},"expiresInDays":{"type":"integer","minimum":1,"maximum":90}},"required":["create","sendEmail"]}},"required":["email"]}}}},"responses":{"200":{"description":"Person was already an active member (X-Existing-Resource: true)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"invitation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt","invitation"],"additionalProperties":false}}}},"201":{"description":"Person imported; invitation included when requested","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"invitation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt","invitation"],"additionalProperties":false}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Person limit reached (person_limit_reached), person deactivated by an administrator (person_deactivated), person withdrew their own participation (person_self_revoked), or Idempotency-Key reused with a different body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/persons/{id}":{"get":{"tags":["Persons"],"summary":"Get a person","operationId":"getPerson","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The person","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Not a member of your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"patch":{"tags":["Persons"],"summary":"Update a person","description":"`externalId` is always updatable. Names can only be filled in while empty — once the person has claimed their profile, they own it (409 conflict otherwise). `labels` and `tags` use replace semantics: the provided array becomes the full set. Removing the `employee` label also removes the person from all teams. Requires the `persons:write` scope.","operationId":"updatePerson","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"externalId":{"anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}]},"firstName":{"type":"string","minLength":1,"maxLength":100},"lastName":{"type":"string","minLength":1,"maxLength":100},"labels":{"description":"Replaces both labels. Removing \"employee\" also removes the person from all teams.","maxItems":2,"type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Replaces the full tag set of this person","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":50}}}}}}},"responses":{"200":{"description":"The updated person","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Not a member of your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Person already has a name","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"delete":{"tags":["Persons"],"summary":"Archive a person","description":"Archives the person (they disappear from your talent pool and free up a plan seat). Their data is retained; re-importing via POST /persons reactivates them, unless the person withdrew their own participation (then reactivation requires a new invitation accepted by the person). Requires the `persons:write` scope.","operationId":"archivePerson","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The archived person","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"description":"Stable person id; use in all person endpoints","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"description":"Your own system's identifier (per organization)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","archived"]},"labels":{"description":"Labels within your organization. A person can be both; an empty array means neither (\"other\"). New persons default to [\"candidate\"]; the employee email-domain rule (configured in the dashboard) can add \"employee\" automatically.","type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Free-form tags, unique per organization (case-insensitive), sorted alphabetically","type":"array","items":{"type":"string"}},"joinedVia":{"description":"How the person entered your pool, e.g. api, invitation_link, invitation_personal","type":"string"},"sharedExistingProfile":{"description":"Whether the person consented to sharing results from assessments taken before joining","type":"boolean"},"assessment":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","completed"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"count":{"description":"Number of completed assessments","type":"number"}},"required":["status","completedAt","count"],"additionalProperties":false},"memberSince":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"archivedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","email","firstName","lastName","externalId","status","labels","tags","joinedVia","sharedExistingProfile","assessment","memberSince","updatedAt","archivedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"No active person with this id","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/persons/{id}/results":{"get":{"tags":["Results"],"summary":"Get a person's assessment results","description":"Cumulative results over all completed assessments: motivation-need scores per axis, competency aptitudes with band, and the AI personality description. Requires the `results:read` scope.","operationId":"getPersonResults","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Results, or hasResults: false when none yet","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"personId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"hasResults":{"description":"false when the person has no completed assessment yet","type":"boolean"},"totals":{"anyOf":[{"type":"object","properties":{"assessments":{"type":"number"},"responses":{"type":"number"}},"required":["assessments","responses"],"additionalProperties":false},{"type":"null"}]},"motivationAxes":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"needs":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"definition":{"type":"string"},"isAnchor":{"type":"boolean"},"score":{"description":"0-1, cumulative over all completed assessments","type":"number"},"exposure":{"type":"number"}},"required":["name","definition","isAnchor","score","exposure"],"additionalProperties":false}}},"required":["code","name","needs"],"additionalProperties":false}},{"type":"null"}]},"competencies":{"anyOf":[{"type":"object","properties":{"modelName":{"type":"string"},"mappingName":{"type":"string"},"scores":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"score":{"description":"Aptitude 0-1 (0.5 = neutral). Never compare between persons.","type":"number"},"band":{"description":"Aptitude band, symmetric around the neutral midpoint 0.5. high = strong natural aptitude (score >= 0.65), moderate = natural aptitude (0.55-0.65), some = neutral (0.45-0.55), limited = naturally costs more energy (< 0.45). Bands describe motivational support, not skill.","type":"string","enum":["limited","some","moderate","high"]}},"required":["competencyId","name","description","score","band"],"additionalProperties":false}}},"required":["modelName","mappingName","scores"],"additionalProperties":false},{"type":"null"}]},"personality":{"anyOf":[{"type":"object","properties":{"markdown":{"type":"string"},"generatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["markdown","generatedAt"],"additionalProperties":false},{"type":"null"}]},"signal":{"description":"Measurement-quality indicator (Dutch UI term: meetkwaliteit). Reflects how consistent and differentiated the answer pattern was, not the person's ability or suitability. groen = high quality, oranje = interpret with some caution, rood = treat results as indicative (an extra session improves reliability). Null when not computable (e.g. imported sessions without response-level data).","anyOf":[{"type":"object","properties":{"score":{"description":"Signal strength 0-1, weighted across all counted sessions","type":"number"},"band":{"type":"string","enum":["groen","oranje","rood"]}},"required":["score","band"],"additionalProperties":false},{"type":"null"}]},"reportUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["personId","hasResults","totals","motivationAxes","competencies","personality","signal","reportUrl"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Not an active member of your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/persons/{id}/report":{"get":{"tags":["Results"],"summary":"Download the person's PDF report","operationId":"getPersonReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The assessment report as application/pdf"},"202":{"description":"The report is still being prepared (AI texts or PDF are generated in the background). Retry after the number of seconds in the Retry-After header; the JSON body is { status: \"preparing\", pending: string[], retryAfterSeconds: number }."},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Not an active member, or no completed assessment yet","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/persons/{id}/matches":{"get":{"tags":["Results"],"summary":"Match a person against all profiles","description":"How this person matches each competency profile, sorted best-first. Intra-individual, so the full per-competency breakdown is included. Requires the `results:read` scope.","operationId":"getPersonMatches","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Matches per profile","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"personId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"hasResults":{"type":"boolean"},"matches":{"type":"array","items":{"type":"object","properties":{"profileId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"matchPercentage":{"description":"Aggregated match 0-100, rescaled to the attainable range of each profile (100 = best possible fit); comparable across profiles for this person","type":"number"},"category":{"type":"string","enum":["low","moderate","high"]},"coverage":{"type":"number"},"confidence":{"type":"number"},"breakdown":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"weight":{"type":"number"},"aptitudeScore":{"description":"0-1; null when the person has no score for this competency","anyOf":[{"type":"number"},{"type":"null"}]}},"required":["competencyId","name","weight","aptitudeScore"],"additionalProperties":false}}},"required":["profileId","title","matchPercentage","category","coverage","confidence","breakdown"],"additionalProperties":false}}},"required":["personId","hasResults","matches"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Not an active member of your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/profiles":{"get":{"tags":["Profiles"],"summary":"List competency profiles","operationId":"listProfiles","responses":{"200":{"description":"All profiles of your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"competencies":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"type":"number"}},"required":["competencyId","name","weight"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","title","description","competencies","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"post":{"tags":["Profiles"],"summary":"Create a competency profile","description":"Creates a profile from a weighted competency selection. Entries can come verbatim from POST /api/v1/profiles/analyze, or be built manually with ids from GET /api/v1/competencies. The profile counts toward your plan's profile limit. Supports the `Idempotency-Key` header. Requires the `profiles:write` scope.","operationId":"createProfile","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"sourceText":{"description":"Optional vacancy text this profile was derived from","type":"string","maxLength":20000},"entries":{"minItems":1,"maxItems":30,"type":"array","items":{"type":"object","properties":{"competencyId":{"description":"Competency id from GET /api/v1/competencies","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"weight":{"description":"Weight level: 1 = crucial, 0.6 = important, 0.3 = desirable","anyOf":[{"type":"number","const":1},{"type":"number","const":0.6},{"type":"number","const":0.3}]}},"required":["competencyId","weight"]}}},"required":["title","entries"]}}}},"responses":{"201":{"description":"The created profile","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"competencies":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"type":"number"}},"required":["competencyId","name","weight"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","title","description","competencies","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body, or entries rejected server-side (details.code: duplicate_competency, unknown_competency, ...)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Profile limit reached (profile_limit_reached, with details.used/limit/plan) or Idempotency-Key reused with a different body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/profiles/analyze":{"post":{"tags":["Profiles"],"summary":"Analyze a vacancy text","description":"AI-analyzes a plain vacancy text against the competency model and returns a weighted competency suggestion plus runners-up. The returned entries fit POST /api/v1/profiles directly, so analyze → review → create is the intended flow. Plain text only: fetch web pages or convert files (PDF/DOCX) to text yourself. This call can take up to a minute for long texts. Requires the `profiles:write` scope.","operationId":"analyzeVacancy","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"text":{"description":"Plain vacancy text (100-20,000 characters). Fetch web pages or convert files to text yourself before calling.","type":"string","minLength":100,"maxLength":20000}},"required":["text"]}}}},"responses":{"200":{"description":"The suggested competency selection","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"suggestedTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"suggestedDescription":{"anyOf":[{"type":"string"},{"type":"null"}]},"entries":{"description":"The suggested weighted selection. Each entry's { competencyId, weight } can be passed verbatim as the entries of POST /api/v1/profiles.","type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"description":"1 = crucial, 0.6 = important, 0.3 = desirable","type":"number"},"motivation":{"description":"Why this competency was selected, in Dutch","type":"string"}},"required":["competencyId","name","weight","motivation"],"additionalProperties":false}},"runnersUp":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"description":"1 = crucial, 0.6 = important, 0.3 = desirable","type":"number"},"motivation":{"description":"Why this competency was selected, in Dutch","type":"string"},"replacesCompetencyId":{"description":"The selected competency this runner-up would replace when swapped in","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"condition":{"description":"When the swap makes sense, in Dutch","type":"string"}},"required":["competencyId","name","weight","motivation","replacesCompetencyId","condition"],"additionalProperties":false}}},"required":["suggestedTitle","suggestedDescription","entries","runnersUp"],"additionalProperties":false}}}},"400":{"description":"Invalid request body (text must be 100-20,000 characters)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"502":{"description":"The analysis failed (analysis_failed); retry or create the profile manually","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/profiles/{id}":{"get":{"tags":["Profiles"],"summary":"Get a competency profile","operationId":"getProfile","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The profile","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"competencies":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"type":"number"}},"required":["competencyId","name","weight"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","title","description","competencies","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Profile not found in your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"patch":{"tags":["Profiles"],"summary":"Update a competency profile","description":"Updates the title and/or description, and/or replaces the full competency set (`entries` uses replace semantics). Requires the `profiles:write` scope.","operationId":"updateProfile","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"entries":{"description":"Replaces the full competency set of this profile","minItems":1,"maxItems":30,"type":"array","items":{"type":"object","properties":{"competencyId":{"description":"Competency id from GET /api/v1/competencies","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"weight":{"description":"Weight level: 1 = crucial, 0.6 = important, 0.3 = desirable","anyOf":[{"type":"number","const":1},{"type":"number","const":0.6},{"type":"number","const":0.3}]}},"required":["competencyId","weight"]}}}}}}},"responses":{"200":{"description":"The updated profile","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"competencies":{"type":"array","items":{"type":"object","properties":{"competencyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"weight":{"type":"number"}},"required":["competencyId","name","weight"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","title","description","competencies","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body or rejected entries","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Profile not found in your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"delete":{"tags":["Profiles"],"summary":"Delete a competency profile","description":"Deletes the profile and its weighting. Match rankings are computed on the fly, so nothing else is affected. Requires the `profiles:write` scope.","operationId":"deleteProfile","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The profile was deleted","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deleted":{"type":"boolean","const":true},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["deleted","id"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Profile not found in your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/profiles/{id}/matches":{"get":{"tags":["Results"],"summary":"Rank your talent pool against a profile","description":"All active persons ranked by aggregated match percentage. Deliberately excludes per-competency scores: ipsative scores are not comparable between persons. Requires the `results:read` scope.","operationId":"getProfileMatches","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ranked matches plus persons without results","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"profileId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"matches":{"type":"array","items":{"type":"object","properties":{"personId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"type":"string"},"matchPercentage":{"description":"Aggregated match 0-100, rescaled to the attainable range of this profile (100 = best possible fit); the only score that may be compared between persons","type":"number"},"category":{"type":"string","enum":["low","moderate","high"]},"lowCoverage":{"description":"true when the match is based on limited data","type":"boolean"},"lastAssessmentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["personId","firstName","lastName","email","matchPercentage","category","lowCoverage","lastAssessmentAt"],"additionalProperties":false}},"personsWithoutResults":{"type":"array","items":{"type":"object","properties":{"personId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"type":"string"},"assessmentStatus":{"type":"string","enum":["not_started","in_progress"]}},"required":["personId","firstName","lastName","email","assessmentStatus"],"additionalProperties":false}}},"required":["profileId","matches","personsWithoutResults"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Profile not found in your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/competencies":{"get":{"tags":["Profiles"],"summary":"List the competency model","description":"All competencies of the default competency model — the source of valid `competencyId` values for profile writes. The need-to-competency mapping weights are internal and never exposed. Requires the `profiles:read` scope.","operationId":"listCompetencies","responses":{"200":{"description":"The competencies of the default model","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"modelName":{"anyOf":[{"type":"string"},{"type":"null"}]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Use as competencyId in profile entries","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","slug","name","description"],"additionalProperties":false}}},"required":["modelName","data"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/tags":{"get":{"tags":["Persons"],"summary":"List your organization's tags","description":"All tags of your organization with usage counts, sorted alphabetically. Use this to reuse existing tags when importing or updating persons instead of introducing near-duplicates. Tags are created on first use via persons writes. Requires the `persons:read` scope.","operationId":"listTags","responses":{"200":{"description":"The organization's tags","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"Display casing as first used; matching is case-insensitive","type":"string"},"usageCount":{"description":"Number of persons carrying this tag","type":"number"}},"required":["id","name","usageCount"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/invitations":{"get":{"tags":["Invitations"],"summary":"List invitations","operationId":"listInvitations","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","accepted","expired","revoked"]}},{"name":"email","in":"query","schema":{"type":"string"},"description":"Exact match"},{"name":"updatedAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"A page of invitations","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"description":"Opaque cursor for the next page; pass as ?cursor=","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false}}}},"400":{"description":"Invalid filter or cursor","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"post":{"tags":["Invitations"],"summary":"Invite a person to take an assessment","description":"Creates a personal invitation with a unique link. With `sendEmail: true` Talentlead emails the person; otherwise send the returned `url` from your own system. If the email belongs to a person who already completed an assessment, the invitation becomes an access request (`variant: access_request`): the person is asked to share the existing profile instead of taking a new assessment. An existing pending invitation for the same email is returned instead (200 + `X-Existing-Resource: true`). Supports the `Idempotency-Key` header. Requires the `invitations:write` scope.","operationId":"createInvitation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"firstName":{"type":"string","minLength":1,"maxLength":100},"lastName":{"type":"string","minLength":1,"maxLength":100},"externalId":{"type":"string","minLength":1,"maxLength":255},"labels":{"description":"Labels applied when the invitation is accepted: \"candidate\" and/or \"employee\". Omitted: defaults to [\"candidate\"].","maxItems":2,"type":"array","items":{"type":"string","enum":["candidate","employee"]}},"tags":{"description":"Tags applied when the invitation is accepted","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":50}},"sendEmail":{"description":"true: Talentlead sends the invitation email; false: you send the returned url yourself","type":"boolean"},"expiresInDays":{"description":"Validity in days (default 30, max 90)","type":"integer","minimum":1,"maximum":90},"message":{"description":"Personal message included in the invitation email and its reminders","type":"string","minLength":1,"maxLength":500}},"required":["email","sendEmail"]}}}},"responses":{"200":{"description":"Existing pending invitation returned (X-Existing-Resource: true)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Person limit reached (person_limit_reached) or Idempotency-Key reused with a different body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/invitations/{id}":{"get":{"tags":["Invitations"],"summary":"Get an invitation","operationId":"getInvitation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The invitation","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Invitation not found in your organization","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"delete":{"tags":["Invitations"],"summary":"Revoke an invitation","operationId":"revokeInvitation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The revoked invitation","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Invitation not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Only pending invitations can be revoked","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/invitations/{id}/resend":{"post":{"tags":["Invitations"],"summary":"Resend the invitation email","description":"Limited to 3 sends per invitation per 24 hours.","operationId":"resendInvitation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Email sent; emailSentAt updated","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}]},"personId":{"description":"Linked person; set at creation when known, otherwise at accept","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"type":"string","enum":["pending","accepted","expired","revoked"]},"labels":{"description":"Labels applied when the invitation is accepted; null means the default (\"candidate\") plus the employee email-domain rule","anyOf":[{"type":"array","items":{"type":"string","enum":["candidate","employee"]}},{"type":"null"}]},"tags":{"description":"Tags applied when the invitation is accepted","anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"variant":{"description":"assessment: invitation to take the assessment; access_request: the person already completed an assessment and is asked to share the existing profile","type":"string","enum":["assessment","access_request"]},"message":{"description":"Personal message included in the invitation email and its reminders","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"Unique invitation link; send this yourself when sendEmail was false","type":"string"},"emailSentAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","firstName","lastName","externalId","personId","status","labels","tags","variant","message","url","emailSentAt","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Invitation not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Only pending invitations can be resent","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"502":{"description":"Email could not be sent","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","operationId":"listWebhooks","responses":{"200":{"description":"Your webhook endpoints","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"description":"[\"*\"] or a subset of: assessment.completed, person.created, person.joined, person.archived, invitation.accepted, invitation.revoked, invitation.expired, ping","type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"secret":{"description":"Signing secret — returned ONLY on creation, store it now","type":"string"},"secretPreview":{"type":"string"},"lastSuccessAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","url","description","events","status","secretPreview","lastSuccessAt","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook endpoint","description":"Maximum 10 endpoints per organization. The signing secret is returned once, on creation only.\n\nDeliveries are signed with your endpoint secret. Header `Talentlead-Signature: t=<unix>,v1=<hex>` where `v1 = HMAC-SHA256(secret, \"{t}.{body}\")`. Reject deliveries older than 5 minutes (replay protection). Additional headers: `Talentlead-Event`, `Talentlead-Delivery-Id`. Failed deliveries are retried with backoff (1m, 5m, 30m, 2h) up to 5 attempts.","operationId":"createWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string","maxLength":500},"events":{"description":"Event types to receive, or [\"*\"] for all","minItems":1,"type":"array","items":{"type":"string"}}},"required":["url","events"]}}}},"responses":{"201":{"description":"Endpoint created; response includes the secret exactly once","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"description":"[\"*\"] or a subset of: assessment.completed, person.created, person.joined, person.archived, invitation.accepted, invitation.revoked, invitation.expired, ping","type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"secret":{"description":"Signing secret — returned ONLY on creation, store it now","type":"string"},"secretPreview":{"type":"string"},"lastSuccessAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","url","description","events","status","secretPreview","lastSuccessAt","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"409":{"description":"Endpoint limit reached","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook endpoint","operationId":"getWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The endpoint (secretPreview only)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"description":"[\"*\"] or a subset of: assessment.completed, person.created, person.joined, person.archived, invitation.accepted, invitation.revoked, invitation.expired, ping","type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"secret":{"description":"Signing secret — returned ONLY on creation, store it now","type":"string"},"secretPreview":{"type":"string"},"lastSuccessAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","url","description","events","status","secretPreview","lastSuccessAt","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Endpoint not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"patch":{"tags":["Webhooks"],"summary":"Update a webhook endpoint","operationId":"updateWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"events":{"description":"Event types to receive, or [\"*\"] for all","minItems":1,"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]}}}}}},"responses":{"200":{"description":"The updated endpoint","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"description":"[\"*\"] or a subset of: assessment.completed, person.created, person.joined, person.archived, invitation.accepted, invitation.revoked, invitation.expired, ping","type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"secret":{"description":"Signing secret — returned ONLY on creation, store it now","type":"string"},"secretPreview":{"type":"string"},"lastSuccessAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","url","description","events","status","secretPreview","lastSuccessAt","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Endpoint not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook endpoint","operationId":"deleteWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Endpoint deleted","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["deleted","id"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Endpoint not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Send a signed test ping","description":"Sends a signed `ping` event synchronously so you can verify your signature implementation.","operationId":"testWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Result of the test delivery","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"type":"boolean"},"responseStatus":{"anyOf":[{"type":"number"},{"type":"null"}]},"responseBody":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["ok","responseStatus","responseBody"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Endpoint not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}},"/api/v1/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"List recent deliveries","operationId":"listWebhookDeliveries","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"A page of deliveries, newest first","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","failed"]},"attemptCount":{"type":"number"},"nextAttemptAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastAttemptAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastResponseStatus":{"anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","eventType","status","attemptCount","nextAttemptAt","lastAttemptAt","lastResponseStatus","createdAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"description":"Opaque cursor for the next page; pass as ?cursor=","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false}}}},"401":{"description":"Missing, malformed, revoked or expired API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"403":{"description":"Plan without API access (plan_upgrade_required), inactive subscription for writes (subscription_inactive), or missing scope (insufficient_scope)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"404":{"description":"Endpoint not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded; see Retry-After and X-RateLimit-* headers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"description":"Human-readable error message (English)","type":"string"},"code":{"description":"Stable machine-readable error code, e.g. person_limit_reached","type":"string"},"details":{"description":"Optional structured context"}},"required":["error","code"],"additionalProperties":false}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key (tl_live_...)","description":"API key from the Talentlead dashboard (Organisatie → API)."}}}}