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

# Authentication and Quota

> Authenticate System API requests and convert account and API-key quota units.

## Overview

The System API manages resources in your MixRoute account, including API keys, Smart Routing keys, and wallet operations. It is separate from the model inference API.

| Purpose                    | Base URL                     | Credential                   |
| -------------------------- | ---------------------------- | ---------------------------- |
| Account and key management | `https://api.mixroute.ai`    | System access token          |
| Model inference            | `https://api.mixroute.ai/v1` | API key beginning with `sk-` |

<Warning>
  A system access token grants account-level management access. Never place it in browser code, mobile applications, logs, or source control.
</Warning>

## Get a system access token

Open **Account Settings → API Access** in the [MixRoute Console](https://console.mixroute.ai/settings), then generate and copy a system access token. Store it in a secrets manager.

<Warning>
  `GET /api/user/token` generates a new system access token. It is a rotation operation, not a read operation, and invalidates the previous token. Do not call it during routine automation.
</Warning>

Set the values used by the examples:

```bash theme={null}
export BASE_URL="https://api.mixroute.ai"
export ACCESS_TOKEN="YOUR_SYSTEM_ACCESS_TOKEN"
export USER_ID="YOUR_NUMERIC_USER_ID"
```

The numeric user ID is shown in the account settings page.

## Authentication headers

Every protected System API request requires both headers:

```http theme={null}
Authorization: Bearer YOUR_SYSTEM_ACCESS_TOKEN
New-Api-User: YOUR_NUMERIC_USER_ID
```

For requests with a JSON body, also send:

```http theme={null}
Content-Type: application/json
```

The user ID must belong to the system access token. Authentication failures do not use a single HTTP status: missing credentials or a user-ID mismatch can return HTTP `401`, while an invalid access token currently returns HTTP `200` with `success: false`. Always check both the HTTP status and the response envelope.

Use this request to verify authentication without changing account data:

```bash theme={null}
curl -fsS "$BASE_URL/api/user/self" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  | jq -e '
      if .success == true then .data
      else error(.message // "authentication failed")
      end
    '
```

## Response envelope

Most System API endpoints use this envelope:

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {}
}
```

Some validation and authentication failures return HTTP `200` with `success: false`, so check both the HTTP status and the `success` field.

```bash theme={null}
response=$(curl -fsS "$BASE_URL/api/user/self/groups" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID")

jq -e '.success == true' <<< "$response" >/dev/null || {
  jq -r '.message // "System API request failed"' <<< "$response" >&2
  exit 1
}
```

## Quota units

Account quota and API-key quota are stored in internal quota units, not directly in USD. Read the current conversion from the public status endpoint:

```bash theme={null}
quota_per_unit=$(curl -fsS "$BASE_URL/api/status" \
  | jq -er '.data.quota_per_unit')

usd_amount=20
internal_quota=$((usd_amount * quota_per_unit))
printf 'Quota for $%s: %s\n' "$usd_amount" "$internal_quota"
```

Use these formulas:

```text theme={null}
internal quota = USD amount × quota_per_unit
USD amount     = internal quota ÷ quota_per_unit
```

<Note>
  `quota_per_unit` is deployment configuration and can change. Retrieve it instead of hard-coding the current value.
</Note>

### Account balance versus key quota

* Account balance (`GET /api/user/self`, field `quota`) is the wallet balance available to the account.
* Key quota (`remain_quota`) is a spending ceiling for one API key.
* Assigning a key quota does not transfer funds out of the wallet.
* `unlimited_quota: true` removes the key-level ceiling, but requests still consume account balance.

Read and display the current account balance:

```bash theme={null}
user=$(curl -fsS "$BASE_URL/api/user/self" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID")

quota_per_unit=$(curl -fsS "$BASE_URL/api/status" \
  | jq -er '.data.quota_per_unit')

jq --argjson unit "$quota_per_unit" '{
  user_id: .data.id,
  internal_quota: .data.quota,
  balance_usd: (.data.quota / $unit)
}' <<< "$user"
```

## Available groups

Use the account-specific group list when creating a key:

```bash theme={null}
curl -fsS "$BASE_URL/api/user/self/groups" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" | jq '.data'
```

Do not assume that a group available to another account is available to yours. The `default` group is suitable for most examples in this guide.

## Security checklist

* Keep the system access token server-side.
* Use a dedicated account or token for automation.
* Never log reveal-endpoint responses.
* Give each API key a clear name, expiration, quota, and IP restriction where possible.
* Rotate by creating a replacement first, then disable and delete the old key after traffic moves.
