API Keys & Scopes
Every integration with LeftFold authenticates via an API key. Keys are scoped to control what each client can do.
Overview
API keys are prefixed with sk_ followed by 64 hex characters. They are shown once at creation and stored as a SHA-256 hash — if you lose a key, create a new one.
Every key belongs to a user and inherits that user's workspace. Keys carry a set of scopes that determine which APIs the key can access. Some scopes require a paid subscription.
Creating Keys
From the dashboard
Navigate to Settings → API Keys and click Create Key. Give it a name (e.g. "Claude Desktop"), select the scopes you need, and copy the key immediately.
From the CLI
LeftFold keys create --name claude-desktopStore the key as an environment variable. The conventional name is LEFTFOLD_API_KEY.
export LEFTFOLD_API_KEY=sk_a1b2c3d4...Authentication
All LeftFold APIs accept a bearer token in the Authorization header. Two token types are supported:
- API key —
sk_prefix, for programmatic access - OAuth JWT — from Supabase Auth (magic link, Google, or GitHub sign-in)
With fetch
const res = await fetch("https://your-project.supabase.co/functions/v1/http-api/articles", {
headers: {
"Authorization": `Bearer ${process.env.LEFTFOLD_API_KEY}`,
},
});
const articles = await res.json();With curl
curl https://your-project.supabase.co/functions/v1/http-api/articles \
-H "Authorization: Bearer sk_your_api_key"Scopes
Each API key carries a set of scopes that control access. When creating a key, select only the scopes the client needs.
| Scope | Description | Paid only |
|---|---|---|
| profile:read | View your profile | No |
| email:read | See your email address | No |
| api:read | Read your data via the HTTP API | No |
| api:write | Create and modify data via the HTTP API | Yes |
| mcp:read | Read via MCP (Claude Desktop, Cursor, etc.) | No |
| mcp:write | Write via MCP | Yes |
| extension:unlock | Activate the Chrome extension | Yes |
| content:read | Read published content via the delivery API | No |
If a key tries to access an endpoint that requires a scope it doesn't have, the API returns 403 Forbidden. If the scope requires a paid subscription and the user's trial has expired, the API returns 402 Payment Required.
License Activation
Extensions and desktop apps use license activation to bind an API key to a specific device. This prevents a single key from being shared across unlimited installs.
The activation flow works by calling the validate-license endpoint with an instanceId — a stable identifier unique to the device (e.g. a UUID stored in chrome.storage.local).
POST /functions/v1/validate-license
Authorization: Bearer sk_...
Content-Type: application/json
{
"instanceId": "browser-ext-a1b2c3d4"
}The response includes activation status, usage counts, and plan limits. Extensions cache this response locally (24-hour TTL) and re-validate on expiry, with a 7-day offline grace period.
Users can view and revoke device activations at Settings → Devices in the dashboard.
Key Rotation
There is no automatic key rotation. To rotate a key:
- Create a new key with the same scopes
- Update the key in your client (environment variable, config file, or extension settings)
- Verify the new key works
- Revoke the old key from the dashboard
Both keys work simultaneously until you revoke the old one, so there is no downtime during rotation.