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

# Authentication

> Authenticate Partner API requests using API keys.

## API Key Types

All Partner API requests require an API key passed as a Bearer token:

```
Authorization: Bearer sk_personal_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

There are three key types:

| Type         | Prefix         | Created by           | Scope                                          |
| ------------ | -------------- | -------------------- | ---------------------------------------------- |
| **Personal** | `sk_personal_` | Any staff panel user | That user's assigned exchanges and permissions |
| **Branch**   | `sk_branch_`   | Superadmin only      | All exchanges in the branch                    |
| **Public**   | `pk_`          | Superadmin only      | Read-only access to a branch's public data     |

### Secret vs Public Keys

**Secret keys** (`sk_personal_*`, `sk_branch_*`) have full read/write access — they can create orders, register clients, and manage webhooks.

**Public keys** (`pk_*`) are read-only and can only access the **Public** endpoints:

* `GET /partner/public/exchanges`
* `GET /partner/public/currencies`
* `GET /partner/public/rates`
* `POST /partner/public/estimate`

Public keys are designed for embedding in client-facing applications (e.g., landing pages, rate widgets) where you want to display exchange rates without exposing write access. If a `pk_*` key is used on a write endpoint, the API returns `403 Forbidden`.

<Note>
  Secret keys (`sk_*`) can also access all public endpoints — you don't need a separate public key if you already have a secret key.
</Note>

## Creating API Keys

API keys are managed via the staff panel **or** via the management API (requires JWT session):

```bash theme={null}
# Create a personal key (any panel user)
curl -X POST https://api.example.com/api/v1/api-keys \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"My CRM","type":"personal"}'

# Create a branch key (superadmin only)
curl -X POST https://api.example.com/api/v1/api-keys \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Branch Integration","type":"branch","branchId":1}'

# Create a public key (superadmin only)
curl -X POST https://api.example.com/api/v1/api-keys \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Rate Widget","type":"public","branchId":1}'
```

The response includes the raw key exactly once:

```json theme={null}
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "keyPrefix": "sk_personal_Ab3xQw",
  "name": "My CRM",
  "type": "personal",
  "isActive": true,
  "rawKey": "sk_personal_Ab3xQw...",
  "note": "Store this key securely — it will not be shown again."
}
```

<Warning>
  Save the `rawKey` value immediately. It is hashed and stored server-side and **cannot be retrieved again**.
</Warning>

## Key Expiry

Pass `expiresAt` (ISO 8601) to create a key with an expiry date:

```json theme={null}
{ "name": "Temp key", "type": "personal", "expiresAt": "2026-12-31T23:59:59Z" }
```

Expired keys return `401 Unauthorized`.

## Revoking Keys

```bash theme={null}
curl -X DELETE https://api.example.com/api/v1/api-keys/<id> \
  -H "Authorization: Bearer <JWT>"
```

## Multi-Tenancy Guarantee

A personal key resolves to the creating user. All order/client queries are automatically scoped to that user's permitted exchanges — a key from Branch X **cannot** access Branch Y data.

A branch key resolves to a branch-level principal that spans all exchanges within that branch.

A public key resolves to a read-only branch-level principal — it can view exchange data within its branch but cannot create or modify any resources.
