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

> ## Agent Instructions
> Follow the content contract in AGENTS.md.
> Treat text as the canonical explanation; video and screenshots enhance it.
> Do not publish unverified product behavior or duplicate an existing canonical article.

# Authentication

> Create StefanBrain API keys, authenticate requests, and restrict keys with scopes and budgets.

Create API keys in **Settings → Developers**. You must accept the current Developer API terms each time you create a key. StefanBrain shows the complete secret once, at creation.

## Authenticate a request

Send the key as a bearer token:

```http theme={"system"}
Authorization: Bearer stefan_sk_your_key_here
```

You can instead use the API key header:

```http theme={"system"}
x-api-key: stefan_sk_your_key_here
```

An API key has the access of the account that owns it. A missing, invalid, revoked, or unauthorized key returns `401 Unauthorized`.

A `stefan_oat_...` OAuth token from a connected assistant also works on every REST route under `/api/developers/v1`. OAuth tokens have no scopes and no per-key budget. On a standard member account, their usage bills the plan's monthly usage pool. See [Pricing](/developers/pricing).

<Warning>
  Keep API keys server-side. Do not expose them in browser payloads, logs, prompts, or committed configuration files.
</Warning>

## Restrict a key with scopes

When creating a key through `POST /api/developers/keys`, use `scopes` to limit the surfaces that key can access.

This endpoint needs a signed-in StefanBrain browser session; an API key cannot call it. The body takes `name`, `developerTermsAccepted: true`, `developerTermsVersion`, `scopes`, and `monthly_budget_cents`. `developerTermsVersion` must match the current terms version; otherwise the endpoint returns `400` with `requiredDeveloperTermsVersion`. The Settings form does not yet expose scopes or budgets.

Supported scope values are:

* `runs`
* `tools`
* `jobs`
* `mcp`

A scoped key receives `403 api_key_scope_forbidden` on other surfaces. Unknown scope values return `400`; StefanBrain does not ignore them.

Omit `scopes`, or send an empty array, to create a full-access key. Keys created before scopes were introduced have full access.

The job-polling endpoints accept a key with either the `tools` or `jobs` scope. A tools-scoped key can poll any job in the account's chats.

The [feedback](/developers/feedback) endpoints accept a key with any scope.

## Set a per-key budget

`monthly_budget_cents` caps one key's wallet-billed token spend, at the published rates, for one billing cycle. Image generation, search, and other per-use charges do not count toward it; the account wallet still limits them. The check runs before each request, so the request that crosses the limit can finish over it. At the limit, requests return `429 api_key_budget_exhausted` with `key_budget.budget_cents`, `key_budget.billed_cents`, and `key_budget.resets_at`.

Omit `monthly_budget_cents` for no per-key limit. The account's API wallet still limits total REST spend.

Scopes and budgets are useful for keys issued to a service, integration, or team member. For example, a CI key can use the `tools` scope with a \$10 monthly limit.

See [Errors and retries](/developers/errors-and-retries) for the complete error envelope and retry guidance.

## Replace an API key or disable a compromised key

Replace a key when its owner changes, an integration needs a separate credential, or the secret may have been exposed.

If a key was exposed, revoke it immediately. For a planned rotation, test the replacement before revoking the old key.

### Create the replacement

1. Open [Settings → Developers](https://stefanbrain.com/settings/developers).
2. Create a key with a name that identifies the integration.
3. Accept the current Developer API terms.
4. Store the secret in your application's server-side secret manager. The full secret is shown only once.

If the old key had scopes or a budget, create the replacement through `POST /api/developers/keys` with the same values; the Settings form does not set them. Never put the key in browser code, a screenshot, a support email, or a committed file.

### Update and test your integration

Update the integration's stored credential and reload or redeploy it as needed. Check every environment that used the old key.

Test authentication with a read-only request:

```bash theme={"system"}
curl --fail-with-body https://stefanbrain.com/api/developers/v1/tools \
  -H "Authorization: Bearer $STEFANBRAIN_API_KEY"
```

This check requires a key that can access tools. A successful response proves access to the catalog, not that every workflow works.

### Disable the old key

Return to Developer settings, identify the old key by its name and displayed prefix, and use its **Delete** control.

Requests that still use the old key will fail. Check scheduled integrations as well as the application you just tested.

For a `401` response, check that the integration actually loaded the replacement secret. For scope or budget errors, see [Errors and retries](/developers/errors-and-retries).

If you need support, send the key's name and the error code to [support@stefanbrain.com](mailto:support@stefanbrain.com)—never the secret.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.