Authentication
How a public API key is read and which surface it may call.
Key header
Prefer the dedicated header. The value is the secret shown once when the key is created.
X-Klockwork-Key: kw_live_exampleIf that header is missing, the API reads a bearer token:
Authorization: Bearer kw_live_exampleAnything that does not start with kw_ is treated as no key. A missing or unknown key returns 401 with { "error": "Invalid API key" }. A revoked or expired key returns the same 401.
Partner keys
Create a partner key in the company workspace after the partnership is active. The create form takes a name, an environment (live or test), and at least one scope:
| Scope | Allows |
|---|---|
status:read | GET /api/public/partner/me |
customers:read | GET /api/public/partner/customers |
customers:write | Create a customer and end a customer |
A call without the required scope returns 403 with { "error": "Missing scope" }.
A partner key is rejected unless the partnership status is active. That response is 403 with { "error": "Partner is not active" }.
Test keys are rejected when the API is running with PARTNER_API_ENV=live. The body is { "error": "Test keys are not accepted in this environment" }.
Agency keys
An agency key is created by an agency admin in the workspace. It acts as that agency organization. It cannot call /api/public/partner.
Solo and company subjects
Solo and company calls use the same agency key, plus the account the key is acting for.
Solo requires a talent id (a UUID) or a Clerk user id:
X-Klockwork-Talent: user_...talentId is accepted as a query parameter when the header is absent. A missing value returns 400 with { "error": "X-Klockwork-Talent is required" }. A value that is neither a UUID nor a Clerk user id returns 400 with { "error": "X-Klockwork-Talent must be a talent id or Clerk user id" }. A talent that is not an active talent of the agency returns 403 with { "error": "This Solo account is not an active talent of the agency" }.
Company requires the client row id, which is a UUID:
X-Klockwork-Client: 00000000-0000-4000-8000-000000000000clientId is accepted as a query parameter when the header is absent. A missing value returns 400 with { "error": "X-Klockwork-Client is required" }. A non-UUID returns 400 with { "error": "X-Klockwork-Client must be a client id" }. An archived client, or a client that is not linked to the agency, returns 403 with { "error": "This company is not a linked client of the agency" }.
