Authentication
API keys for humans and agents. No browser required.
Overview
The Patina API uses Bearer token authentication with API keys. Every request must include an Authorization header with a valid key.
curl https://patina.so/api/v1/workspaces/YOUR_WORKSPACE_ID/playbooks \
-H "Authorization: Bearer pk_YOUR_API_KEY" API keys start with the prefix pk_ followed by a 64-character hex string. Keys are hashed
before storage — Patina never stores your key in plaintext.
Two types of keys
Patina has two kinds of API keys, for two kinds of principals:
User keys
Tied to your user account. Carry your full permissions across all workspaces you belong to. Best for personal scripts, CI pipelines, and admin tasks.
Create them in Workspace Settings → API Keys, or via the API.
Agent keys
Tied to a registered agent within a single workspace. The agent inherits the role you assign it (viewer, editor, or owner) and is scoped to that workspace only. Best for AI tools, bots, and automated integrations.
Create them via the Agents API.
Create a user API key
You can create keys from the Patina UI (Workspace Settings → API Keys) or programmatically. To create a key via the API, you need an existing key or an active browser session:
curl -X POST https://patina.so/api/v1/workspaces/YOUR_WORKSPACE_ID/keys \
-H "Authorization: Bearer pk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "CI pipeline"}' The response includes the full key — this is the only time it's shown:
{
"id": "key_abc123...",
"label": "CI pipeline",
"key": "pk_9f3a1b2c4d5e6f7890abcdef12345678...",
"prefix": "pk_9f3a1b2c",
"createdAt": "2025-03-15T10:30:00.000Z"
} Store this key securely. If you lose it, you'll need to create a new one. You can revoke keys at any time.
Create an agent API key
Agent keys require two steps: register the agent, then create a key for it. Only human users can manage agents — agents cannot create other agents.
# 1. Create an agent
curl -X POST https://patina.so/api/v1/workspaces/YOUR_WORKSPACE_ID/agents \
-H "Authorization: Bearer pk_YOUR_USER_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "deploy-bot", "role": "viewer"}'
# 2. Create a key for that agent
curl -X POST https://patina.so/api/v1/workspaces/YOUR_WORKSPACE_ID/agents/AGENT_ID/keys \
-H "Authorization: Bearer pk_YOUR_USER_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "production"}' The agent key works exactly like a user key in the Authorization header, but its
permissions are scoped to the agent's role within that workspace. See Agents for the full API.
Verify a key
Use the key info endpoint to check which workspace and owner type a key resolves to:
curl https://patina.so/api/v1/auth/key-info \
-H "Authorization: Bearer pk_YOUR_API_KEY" {
"workspaceId": "ws_abc123...",
"ownerType": "user"
} Roles and permissions
Every principal (user or agent) has a role within each workspace:
| Role | Read | Create & Edit | Delete & Admin |
|---|---|---|---|
| Viewer | Yes | No | No |
| Editor | Yes | Yes | No |
| Owner | Yes | Yes | Yes |
Agent roles are capped by the sponsor user's role — an agent can never have higher permissions than the user who created it.
Error responses
Authentication failures return a structured JSON error:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or revoked API key."
}
} Common auth error codes:
401 UNAUTHORIZED— missing, invalid, or revoked API key403 FORBIDDEN— valid key but insufficient role for this action404 NOT_FOUND— valid key but not a member of this workspace
Workspace membership is checked on every request. If the key resolves but the principal isn't a
member of the target workspace, the API returns 404 (not 403) to avoid
leaking workspace existence.