sf_live_<base64url>. Keys are shown exactly once at creation and stored hashed (Argon2) on the server. Every authenticated route accepts a key in Authorization: Bearer sf_live_....
There is no public GET /api/keys/{id} — once created, the raw secret is only available from the create response.
API keys
List keys
Authorization: Bearer sf_live_... or browser session.
Response 200
keyPrefix is the first 12 characters and is safe to display. Revoked keys are returned with revokedAt set; they cannot authenticate any new request.
Create a key
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
name | string | optional | "Unnamed Key" | Human label. Shown in the dashboard and GET /api/keys. |
key field is the only time the raw secret is returned. Store it now.
Revoke a key
Curl
CLI auth handshake (sf login)
The CLI cannot accept a Supabase password locally, so it runs a three-endpoint handshake that proxies the browser session into a fresh API key.
POST /api/auth/cli — initialize
Auth: none (the sessionToken is the shared secret).
Body
| Field | Type | Required | Notes |
|---|---|---|---|
sessionToken | string | yes | At least 32 characters. CLI generates this with a CSPRNG. |
| Status | Body | Cause |
|---|---|---|
400 | { "error": "Invalid JSON" } | Body is not valid JSON. |
400 | { "error": "Invalid session token" } | Missing or shorter than 32 chars. |
409 | { "error": "Session already exists" } | Token collision — generate a new one. |
500 | { "error": "Internal error" } | Server failure. |
GET /api/auth/cli/poll?token=... — poll for the key
Auth: none. The session token is the shared secret.
Response 200 (pending)
| Status | Body | Cause |
|---|---|---|
400 | { "error": "token required" } | ?token= is missing. |
410 | { "status": "expired" } | Session expired (5 min TTL) or already consumed. |
POST /api/auth/cli/complete — browser callback
This is what the browser hits after Supabase login. CLI integrators don’t call it directly.
Auth: Supabase session cookie (browser-side).
Body
| Field | Type | Required | Notes |
|---|---|---|---|
sessionToken | string | yes | Must match the token created by POST /api/auth/cli and not yet have an apiKey attached. |
| Status | Body | Cause |
|---|---|---|
400 | { "error": "Invalid JSON" } or { "error": "sessionToken required" } | Bad body. |
401 | { "error": "Not authenticated" } | No Supabase session. |
410 | { "error": "Session expired or already used" } | Session expired or already converted. |
"CLI (browser login)" so users can see it in the dashboard and revoke it later.
Signup
https://simplefunctions.dev/signup for the standard flow; this endpoint is mainly for programmatic onboarding.
See also
Authentication
All auth flavors — API key, browser session, BYOK exchange creds.
Direct API access
First curl calls and language examples.
API keys (enterprise)
Rotation policy and per-tool restriction.
Errors
Full error envelope reference.