Skip to content

Authentication

All three API surfaces — the OpenAI-compatible /v1 API, the MCP servers, and the platform REST API — authenticate with the same bearer token: a workspace API key, created from Settings → API Keys.

Authorization: Bearer sk-octo_...

A missing or invalid key returns 401 with an OpenAI-shaped error envelope (code: "invalid_api_key"), which the OpenAI SDK raises as an AuthenticationError. See Errors for the full table.

Every key resolves to { userId, workspaceId, role }:

  • workspaceId — every turn, tool call, and conversation created through the key is scoped to this workspace. The key is a workspace credential, not a purely personal one — see Get an API key for who can see and revoke it.
  • role (owner / admin / agent) — filters the tool catalog exactly as it does in the dashboard. A lower-privileged key sees fewer tools; the same request made with an owner-rooted key and an agent-rooted key can produce different available actions.

Conversations created through the API belong to the workspace, not to the individual key that started them. Any key in the workspace can continue or read any conversation in that workspace (via previous_response_id or conversation — see Statefulness). This mirrors how Octo’s work belongs to the workspace everywhere else in the product.

This is the part to actually read before wiring up automation:

An API key inherits its owner’s full role, and there is no step-up second factor over the API — the same key both asks for and confirms a risky action (see Confirmations). A leaked key can spend up to the account’s limits.

Mitigations that exist today:

  • Per-key and per-workspace rate limits.
  • The same cumulative spend / mass-message thresholds that apply everywhere else in the product.

Not yet available: restricted-scope keys (read-only, no-spend, or tool-allowlisted keys) are a deferred follow-up. Until then, treat every API key like a password — don’t commit it, don’t log it, and rotate it immediately if it’s ever exposed.