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

# API keys

> Make an API key and choose what it can do.

Most calls to the API need an API key. This page shows how to make one and what each access level allows. It ends with what to do if a key leaks.

## Make a key

Make a key in the [console](https://console.sqwish.ai), on the **API keys** page. You choose its [access](#access-levels) as you make it. The console shows a new key once, so copy it then. OneHot keeps no copy you can read, so if you lose a key, make a new one and revoke the old one.

Your personal workspace can have keys once it is off the waitlist. Until then, making one gets `403 waitlisted`. A shared organisation can have keys from the start. A suspended account can't make keys, and gets `403 access_required`. Name a key after the service that uses it, such as `support-router-production`, in 1 to 64 characters.

Set the key as `SQWISH_API_KEY`. The Python and TypeScript clients read it from there.

```bash theme={null}
export SQWISH_API_KEY='onehot_sk_...'
```

Send the key as a bearer token, in an `Authorization: Bearer <key>` header, over HTTPS:

```bash theme={null}
curl --fail-with-body https://api.sqwish.ai/v1/models \
  -H "Authorization: Bearer $SQWISH_API_KEY"
```

A key belongs to its account. Keep it out of browser bundles and source control. Use a separate key for each application. Then usage is easier to understand, and access easier to revoke.

An account is `waitlisted`, `active` or `blocked`. Decisions and fine-tuning need a key from an active account, and so does most other API work. A waitlisted account can see where it stands and browse models. It can read `/v1/account`, `/v1/organization` and `/v1/models` ([Access](https://docs.sqwish.ai/guides/account.md#access)).

## Access levels

You choose a key's access when you make it. To change a key's access, make a new key.

| Access | `scope` | The key can |
| - | - | - |
| Full access | `full` | Call everything a project key can |
| Inference | `inference` | Make decisions: `/v1/decide` and its estimate, the [Jev routes](https://docs.sqwish.ai/guides/jev-migration.md) under `/v1/systemone`, and the Claude Code hook. Read models, families and `/v1/onehot`. Not the account or the organisation: it can't call `GET /v1/account` or `GET /v1/organization` |
| Read only | `read` | Make every read a project key can, downloads included |

Anything else a key calls gets `403 key_scope`. An inference key can't read usage or the request history either, so give a dashboard a read-only key.

Account changes and the download of the whole account stay in the console. A key that tries them gets `403 console_only`.

For a production service, an inference key limits what a leaked key can do. A [project's spending limit](https://docs.sqwish.ai/guides/projects.md#spending-limits) can also stop the project's new work at a monthly amount.

## List and revoke keys

Make and revoke keys in the console. `GET /v1/organization/keys` lists each key's name, prefix, last use and access. It never shows the secret.

```python Python theme={null}
from sqwishai import OneHot

with OneHot() as client:
    page = client.organization.keys.list(revoked=False)

for key in page["data"]:
    print(key["id"], key["name"], key["prefix"], key["scope"], key["last_used_at"])
```

```typescript TypeScript theme={null}
import { OneHot } from "sqwishai";

const client = new OneHot();
const page = await client.organization.keys.list({ revoked: false });

for (const key of page.data) {
  console.log(key.id, key.name, key.prefix, key.scope, key.last_used_at);
}
```

```bash cURL theme={null}
curl --fail-with-body 'https://api.sqwish.ai/v1/organization/keys?revoked=false' \
  -H "Authorization: Bearer $SQWISH_API_KEY"
```

`prefix` is the start of the key, so you can tell which key a service uses. `last_used_at` is `null` for a key that was never used. Revoke keys you no longer use: an old `last_used_at` marks one.

To revoke a key, choose **Revoke** on its row of the **API keys** page, then **Confirm revoke**. A request with a revoked key gets `401 invalid_api_key`.

## Monthly caps

You can't set a monthly cap on a key: a request that makes a key with `monthly_cap_usd` gets `422 invalid_request`. To stop a service's spending at a monthly amount, give its project a [spending limit](https://docs.sqwish.ai/guides/projects.md#spending-limits).

Some existing keys have a cap. Such a key shows it in `monthly_cap_usd`, and `month_spent_usd` shows what its decisions cost this month. A decision that would take the key past its cap gets `402 key_spend_limit`.

## Project keys and admin keys

In a shared organisation, a key belongs to the organisation, and a project key works in one of its projects. It needs no header there. A request whose `OneHot-Project` header names another project gets `403 key_project` ([Keys and projects](https://docs.sqwish.ai/guides/projects.md#keys-and-projects)).

A project key works as a developer, whoever made it. A route that role can't call, such as the wallet, gets `403 role_forbidden`. Only owners make full-access keys. A developer's key is inference or read, and inference when they don't choose ([Keys in an organisation](https://docs.sqwish.ai/guides/organisations.md#keys-in-an-organisation)).

An [admin key](https://docs.sqwish.ai/guides/organisations.md#admin-keys), whose `scope` is `admin`, is different. It changes the organisation's billing, projects, keys and members, and does no work. It also makes project keys and revokes keys.

In your personal workspace, a key works with the owner's role.

## What a key can't do

A project key with full or read-only access reads its account, but can't change it.

A leaked project key can't make another key, buy credit or change automatic top-ups. Those change in the console, or with an admin key.

A project key's reads leave out the links to a pending checkout, a card set-up or an invoice. The console and an admin key get those links.

## If a key leaks

A key can spend the balance on requests until you revoke it. Revoking stops new requests, not work already started. Jobs run to their end, and keep warm and dataset storage keep renewing. So if a key leaks:

1. Revoke it.
2. Cancel the jobs you didn't start.
3. Switch keep warm off.
4. Turn automatic top-ups off.
5. Check the [request history](https://docs.sqwish.ai/guides/usage.md#diagnose-a-request) for the key's calls. Pass its `id` from `GET /v1/organization/keys` as `api_key_id`.

Or tell us at [security@sqwish.ai](mailto:security@sqwish.ai), and we can suspend the account.

If an admin key leaks, also check the organisation's keys, members and invitations.

## Which key to give a coding agent

A [coding agent](https://docs.sqwish.ai/agent-skills.md) uses a key as your code does, with the same access levels.

| The agent | Give it |
| - | - |
| Makes decisions, through the MCP `decide` tool or the Claude Code hook | An inference key |
| Builds datasets, trains and tunes | A full-access key. In a shared organisation, only an owner makes one |

In a shared organisation, give an agent that trains a project of its own, with a [spending limit](https://docs.sqwish.ai/guides/projects.md#spending-limits). Its work and spending then stay apart from production.


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