# Authentication

> Private trading and account requests use long-lived, scoped tokens that you can revoke from the web app.

<Callout type="info" title="API order placement">
For API trading, use [pre-signed orders](/docs/api-traders/pre-signed-orders).
Server-side signing may slow order ingestion. Follow the
[one-time setup](/docs/api-traders/pre-signed-orders#one-time-setup) and grant
`orders:place_signed` for signed single-order and batch submissions.
</Callout>

## Creating a token [#creating-a-token]

1. Sign in to the web app. (First-time only — after this you can stay
   in your terminal.)
2. Open **Settings → API Tokens**.
3. Click **Create token**, give it a label, choose scopes, and pick
   an optional expiration.
4. **Copy the token right away.** It's shown exactly once. If you
   lose it, revoke it and create a new one — there's no recovery.

A token looks like `agt_` followed by 43 random characters:

```
agt_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhI
```

## Using a token [#using-a-token]

Send it as a bearer credential on private trading and account requests:

```
Authorization: Bearer agt_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhI
```

Ordinary API-token requests need no timestamp or per-request HMAC. Market
discovery, orderbooks, and the market stream are public and should omit this
header. Pre-signed orders and account batches have separate signing rules.

## Scopes [#scopes]

Each token carries a list of scopes set at creation. The platform
enforces them; an out-of-scope request returns the stable
`403 forbidden_scope` Problem Details code. The response does not expose the
missing scope, so your client should know which scope each operation requires.

| Scope                 | Grants                                                                                                                              |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `portfolio:read`      | Reading positions, open orders, fills, summary                                                                                      |
| `orders:read`         | Reading individual order detail                                                                                                     |
| `orders:place`        | Placing server-signed orders                                                                                                        |
| `orders:place_signed` | Placing pre-signed orders, the recommended API trading flow — see [Pre-signed orders](/docs/api-traders/pre-signed-orders)          |
| `orders:cancel`       | Cancelling individual orders                                                                                                        |
| `orders:cancel_all`   | Cancelling everything open                                                                                                          |
| `positions:split`     | Splitting collateral into a complete binary pair on-chain                                                                           |
| `positions:merge`     | Merging a complete binary pair back into collateral on-chain                                                                        |
| `batches:submit`      | Submitting a wallet-signed account batch                                                                                            |
| `account:stream`      | Receiving private order, fill, position, redemption, and collateral changes on the [account-events WebSocket](/docs/account-stream) |

Tokens can also be issued programmatically — see
[Create a personal access token](/docs/api-reference/auth/create_api_token).

Reading the orderbook doesn't require a scope — the
[`GET /trade/v1/orderbook/{token_id}`](/docs/orderbook) endpoint is public.

**Recommended scope set for a trading bot:**

```
portfolio:read
orders:read
orders:place
orders:cancel
orders:cancel_all
account:stream
```

If you only need read-only access (e.g. monitoring your positions),
drop the three `orders:*` scopes that mutate.

## What tokens can't do [#what-tokens-cant-do]

The standard endpoints for these operations require a fresh browser session:

* **Withdrawing funds**
* **Managing your tokens** (creating, listing, revoking)

An account batch can contain a withdrawal only when it also carries the
wallet's valid signature; an API token alone cannot create that signature.
A leaked token can place trades on your behalf, but cannot use the standard
withdrawal endpoint and cannot create replacement API tokens.

## Revoking a token [#revoking-a-token]

Open **Settings → API Tokens** in the web app and click **Revoke**.
The next request that uses that token gets `401` immediately — no
grace period.

The response uses `401 invalid_personal_access_token`; replace the credential
instead of retrying it. See [Errors and recovery](/docs/errors) for the full
failure shape.

If you think a token is compromised:

1. **Cancel any open orders first** — use the same token (assuming
   it has `orders:cancel_all`) or the "Cancel all" button in the
   web app. Resting orders aren't auto-cancelled on revocation.
2. **Then revoke the token.**

## TTL [#ttl]

Tokens don't expire unless you set an `expires_at` at creation. Set an expiry
that matches your credential-rotation policy and replace the token before it
lapses.
