> ## Documentation Index
> Fetch the complete documentation index at: https://docs.simplefunctions.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# API keys

> How SimpleFunctions API keys work — formats, creation, rotation, and revocation.

SimpleFunctions issues two key shapes:

| Shape                 | Surface                                          | Issue at                                         |
| --------------------- | ------------------------------------------------ | ------------------------------------------------ |
| `sf_live_<base64url>` | Landing API + MCP at `simplefunctions.dev`       | `https://simplefunctions.dev/dashboard/keys`     |
| `sft_live_<...>`      | Real-time data API at `data.simplefunctions.dev` | `https://app.simplefunctions.dev/dashboard/keys` |

The two key spaces are separate. A `sf_live_` key does not authenticate against `data.simplefunctions.dev/v1`, and vice versa.

## Create

Create a key from the dashboard at `https://simplefunctions.dev/dashboard/keys`, or programmatically:

```bash theme={null}
curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-agent"}' \
  https://simplefunctions.dev/api/keys
```

**Body**

| Field  | Type   | Required | Notes                                                               |
| ------ | ------ | -------- | ------------------------------------------------------------------- |
| `name` | string | optional | Human label. Defaults to `"Unnamed Key"`. Shown in `GET /api/keys`. |

**Response 201**

```json theme={null}
{
  "id": "key_01J0...",
  "key": "sf_live_aB3D...XYZ",
  "keyPrefix": "sf_live_aB3D",
  "name": "my-agent",
  "message": "Save this key — it will not be shown again."
}
```

The raw `key` value is returned **once**. Store it now — there is no endpoint that returns it again.

See the full schema in [API keys + auth API](/api-reference/keys).

## List

```bash theme={null}
sf me keys --json
curl -H "Authorization: Bearer $SF_API_KEY" "https://simplefunctions.dev/api/keys"
```

The list returns key metadata only (`id`, `name`, `keyPrefix`, `lastUsedAt`, `revokedAt`, `createdAt`). Raw secrets are never re-listed.

## Rotate

Key rotation is "create + revoke": issue a new key, switch your callers, then delete the old one.

```bash theme={null}
# 1. Create the replacement
curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-agent-2026-05"}' \
  https://simplefunctions.dev/api/keys

# 2. Update consumers to the new key

# 3. Revoke the old key
curl -X DELETE -H "Authorization: Bearer $SF_API_KEY" \
  "https://simplefunctions.dev/api/keys/$OLD_KEY_ID"
```

Revocation takes effect immediately.

## Revoke

```bash theme={null}
curl -X DELETE -H "Authorization: Bearer $SF_API_KEY" \
  https://simplefunctions.dev/api/keys/<key-id>
```

Or click **Revoke** in the dashboard. A revoked key fails authentication on the next call.

## What about scopes / per-tool restriction?

The current production API key model is **single-tier per user** — every active key has the same access as the issuing user.

Need scope-limited keys, MCP-tool allow-lists, or service accounts with isolated scopes for a production integration? Email **`patrick@simplefunctions.dev`** with the use case. We will work out the right approach rather than ship a half-finished scope model.

## See also

<CardGroup cols={2}>
  <Card title="Authentication" href="/guides/authentication">
    Where API keys fit in the auth model.
  </Card>

  <Card title="API keys + auth API" href="/api-reference/keys">
    Full HTTP surface and CLI handshake.
  </Card>

  <Card title="Rate limits" href="/enterprise/rate-limits">
    Per-route throttles.
  </Card>

  <Card title="Security" href="/enterprise/security">
    Storage and rotation guarantees.
  </Card>
</CardGroup>
