Skip to content
Guide

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-desktop

Store 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 keysk_ 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.

ScopeDescriptionPaid only
profile:readView your profileNo
email:readSee your email addressNo
api:readRead your data via the HTTP APINo
api:writeCreate and modify data via the HTTP APIYes
mcp:readRead via MCP (Claude Desktop, Cursor, etc.)No
mcp:writeWrite via MCPYes
extension:unlockActivate the Chrome extensionYes
content:readRead published content via the delivery APINo

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:

  1. Create a new key with the same scopes
  2. Update the key in your client (environment variable, config file, or extension settings)
  3. Verify the new key works
  4. Revoke the old key from the dashboard

Both keys work simultaneously until you revoke the old one, so there is no downtime during rotation.