Skip to content

Authentication

Every endpoint except /health requires a bearer token. Two kinds are accepted:

  1. API keys — long-lived, opaque tokens prefixed sf_. Use these for CLIs, server-to-server, and headless MCP clients. Created and revoked on /settings/api-keys.
  2. Clerk session JWTs — short-lived, used implicitly by the dashboard. Not for external clients.

The MCP endpoint (/mcp) additionally accepts OAuth access tokens obtained through the standard MCP sign-in flow — see MCP. Interactive MCP clients should prefer that over API keys; requests authenticated this way are scoped to your default API key.

The header form is identical in both cases:

Authorization: Bearer <token>
StepWhereNotes
CreatePOST /me/keys (or the dashboard)Returns the plaintext once. Hashed at rest.
ListGET /me/keysReturns metadata only — id, name, active, createdAt, tail. Never the plaintext.
RevokeDELETE /me/keys/:idSets active = false. Existing executions remain queryable; new requests with that key return 401 invalid api key.

Lost a key? Revoke it and mint a new one. There is no recovery path.

When you call the API as a signed-in dashboard user, the request defaults to your first active key. To scope a run to a specific key, send the key’s id in X-Use-Api-Key:

Authorization: Bearer <Clerk JWT>
X-Use-Api-Key: k_…

The server verifies the key is yours and active before honouring it. Invalid or foreign ids are ignored silently and the default key is used.

The dashboard sets this header automatically based on the API key dropdown on Run scrape — see Quickstart for the flow.

When you call the API with an sf_… bearer token directly, the request is scoped to that key by definition. X-Use-Api-Key is ignored.

StatusBodyCause
401{ "error": "missing or malformed Authorization header" }No bearer, or scheme wasn’t Bearer.
401{ "error": "invalid api key" }sf_… token doesn’t match any active hash.
401{ "error": "invalid token" }Clerk couldn’t verify the JWT (expired, wrong audience, etc.).
403{ "error": "this endpoint requires a signed-in user" }You called a user-only endpoint (e.g. /me/keys) with an sf_… token.