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

# Authentication

> Ed25519 assertion JWT, access tokens, and scopes.

# Authentication

Partner API uses a two-step handshake:

1. You sign a short **assertion** JWT with your Ed25519 private key
2. Auth returns a short-lived **access** token (EdDSA, IMBA keys)
3. You call Partner API with `Authorization: Bearer <access_token>`

HS256 client / Wallet tokens are **not** accepted.

## Assertion → access token

```http theme={null}
POST https://api.imbawallet.com/auth/v1/partner/token
Content-Type: application/json

{ "assertion": "<JWT>" }
```

### Assertion claims

| Claim          | Required | Notes                          |
| -------------- | -------- | ------------------------------ |
| `iss`          | yes      | Decimal text `partner_id`      |
| `aud`          | yes      | Always `imba-partner-api`      |
| `iat`          | yes      | Issued-at (unix seconds)       |
| `exp`          | yes      | Max 60s from `iat`             |
| `jti`          | yes      | UUID, single-use (anti-replay) |
| `kid` (header) | yes      | Registered credential key id   |
| `alg` (header) | yes      | `EdDSA`                        |

### Access token

| Field        | Value                               |
| ------------ | ----------------------------------- |
| TTL          | 900 seconds                         |
| `partner_id` | number (taken only from this token) |
| `scope`      | space-separated scopes              |
| Signature    | EdDSA (IMBA JWKS)                   |

Never send `partner_id` in the body or URL.

## Scopes

| Scope                  | Purpose                       |
| ---------------------- | ----------------------------- |
| `balance:read`         | Partner balance               |
| `deposit_address:read` | Sticky deposit address        |
| `withdraw`             | Create withdrawals            |
| `cards:issue`          | Issue cards                   |
| `cards:read`           | Read cards / card balance     |
| `cards:topup`          | Top up cards                  |
| `cards:freeze`         | Freeze cards                  |
| `esim:*`               | eSIM catalog + purchase + get |
| `gift:read`            | Gift catalog + get            |
| `gift:purchase`        | Buy gift cards                |
| `gift:*`               | Gift super-scope              |
| `reconciliation:read`  | Ledger reconciliation         |
| `document:read`        | Document by `ext_id`          |

Matching: exact scope, or area wildcard like `cards:*` (covers `cards:issue`).\
`*:*` is not a valid grant. Credentials without explicit money scopes get read-only defaults only (`balance:read`, `deposit_address:read`, `document:read`, `reconciliation:read`).

## Key rotation

1. Generate a new Ed25519 keypair and register a new `kid`
2. Start signing assertions with the new key
3. Ask IMBA to revoke the old `kid` (`revoked_at`)

Keep the private key only on your servers. Card encryption uses a **separate** X25519 key — see [Card encryption](/guides/card-encryption).

## Tenant access state

Even with a valid JWT, a blocked or inactive tenant contract receives `403`. Contact support if access was revoked unexpectedly.
