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

# Authentication

> Mint a workspace API key, send it as a bearer token, and scope and rotate it.

Every request to the ish API carries a bearer token in the `Authorization` header:

```bash theme={null}
curl -sS "$API_URL/api/v1/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $TOKEN"
```

A request with no token, or an invalid one, returns a `401`.

## Mint a workspace key

Create an API key in the product app under **Settings**, then **Developers**. Any member of the workspace can mint one. A key is a workspace-scoped machine principal: it acts on behalf of the workspace, and it only ever reaches the people and sessions that workspace owns.

A key looks like `ish_sk_live_...`. **It is shown once, at creation.** Copy it then; the product app masks it afterward and cannot show it again. Store it in a secret manager or an environment variable, never in client-side code or source control.

<Warning>
  Treat a key like a password. If one leaks, revoke it (below) and mint a replacement. Anyone holding the key has the workspace access its scopes grant.
</Warning>

## Scopes

A key carries any combination of seven scopes. Grant only what the integration needs.

| Scope                | Grants                                                                                 |
| -------------------- | -------------------------------------------------------------------------------------- |
| `sessions:run`       | Create sessions, submit turns, and close sessions (the mutating lane)                  |
| `sessions:read`      | Read a session, list sessions, and read a decision trace                               |
| `environments:read`  | Read the workspace's registered environments                                           |
| `environments:write` | Register, update, and delete environments                                              |
| `tasks:read`         | Read the workspace's registered tasks                                                  |
| `tasks:write`        | Register, update, and delete tasks                                                     |
| `people:read`        | List and search the [people](/api/concepts/people) the workspace can run a session for |
| `people:write`       | Create, edit, archive and restore the workspace's own people, and run generation jobs  |
| `usage:read`         | Read the workspace's session usage series, spend cap and rate-limit budgets            |

A new key is minted with `sessions:run`, `sessions:read`, and `tasks:read`. The task read is a default because a session can bind a registered task by id, so a key that runs sessions but cannot resolve the task it names would be a broken starting point.

No `:write` scope is granted by default. Ask for `environments:write` or `tasks:write` when the integration manages a registry rather than just running against it.

`people:read` is not granted by default either, and for a different reason: a person record carries demographics and a written background about someone the workspace modelled, so reading the pool is a decision the person minting the key should make deliberately. Ask for it when the integration picks its own participants rather than being handed a `person_id`.

`usage:read` is not granted by default and nothing implies it. Usage answers how much the workspace has spent and how fast it may go, which is account information rather than simulation data, so it is a separate decision from running sessions.

`people:write` does not imply `people:read`. They are granted independently, so a key that only feeds people in never gains the ability to read the pool back out. Ask for both when the integration manages a roster it also searches.

A key without the scope an operation requires is refused with `403` and `detail.error_kind = "insufficient_scope"`, which names the `required_scope`. Reading a trace needs `sessions:read`; everything that drives a session needs `sessions:run`.

## Rotate a key

There is no in-place rotation. To rotate, mint a new key, move your integration onto it, then revoke the old one from **Settings**, then **Developers**. Because a workspace can hold several live keys at once, you can overlap the two long enough to cut over with no downtime, then revoke the old key.

Revoking a key takes effect immediately: the next request that presents it returns a `401`.

## User tokens for personal scripts

An ish user access token also works on the same `Authorization: Bearer` header. It is fine for a quick personal script you run as yourself, but it is tied to your user session rather than the workspace, so it is not the right credential for a deployed integration. Use a workspace key for anything machine-to-machine.

## The values you need

The API examples throughout these docs use a few placeholders.

| Placeholder    | What it is                 | Where it comes from                                                      |
| -------------- | -------------------------- | ------------------------------------------------------------------------ |
| `API_URL`      | Your ish API base          | `https://api.ishlabs.io`, or the base URL from your onboarding           |
| `TOKEN`        | Your workspace API key     | Minted in **Settings**, then **Developers**                              |
| `WORKSPACE_ID` | Your workspace id (a UUID) | The workspace the session runs under (the `workspace_id` path parameter) |
| `PERSON_ID`    | The person id (a UUID)     | The [person](/concepts/people) you want to run (the `person_id` field)   |

The person must be [workspace-owned or a platform-library profile](/api/overview#which-people-you-can-run); anything else returns a `403`.

## Related

<Columns cols={2}>
  <Card title="Quickstart" icon="bolt" href="/api/quickstart">
    Put a key to work: create a session and run a turn.
  </Card>

  <Card title="Handling errors" icon="triangle-exclamation" href="/api/guides/session-loop#handling-errors">
    What `401`, `403`, and the rest mean, and how to recover.
  </Card>
</Columns>
