Authentication
Operation and account endpoints require a bearer token. /healthz, /readyz and OAuth discovery are public; Stripe webhook ingress verifies its signature instead. Two bearer kinds are accepted:
- 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. - 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>Lifecycle
Section titled “Lifecycle”| Step | Where | Notes |
|---|---|---|
| Create | POST /me/keys (or the dashboard) |
Returns the plaintext once. Hashed at rest. |
| List | GET /me/keys |
Returns metadata only — id, userId, name, active, createdAt, keyTail. Never the plaintext. |
| Revoke | DELETE /me/keys/:id |
Sets active = false. Existing jobs remain queryable; new requests with that key return 401 UNAUTHENTICATED. |
Lost a key? Revoke it and mint a new one. There is no recovery path.
Picking which key a request belongs to
Section titled “Picking which key a request belongs to”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.
Errors
Section titled “Errors”| Status | Code | Cause |
|---|---|---|
401 |
UNAUTHENTICATED |
Bearer missing, malformed, invalid, expired or revoked. |
403 |
FORBIDDEN |
A user-only endpoint (such as /me/keys) was called with an sf_… token. |
Responses use { "error": { "code": "UNAUTHENTICATED", "message": "Authentication is required." } }. MCP HTTP 401 responses also include the OAuth WWW-Authenticate challenge. See Errors and response contracts.