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

# Authentication

> Obtain and use JWT tokens to authenticate API requests.

All API endpoints (except `/health` and `/auth/token`) require a JWT bearer token.

## Obtaining a Token

Request a token from your participant backend:

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://your-backend.example.com/auth/token
  ```

  ```javascript fetch theme={null}
  const response = await fetch('https://your-backend.example.com/auth/token', {
    method: 'POST',
  });
  const { data } = await response.json();
  console.log(data.token);
  ```

  ```python requests theme={null}
  import requests

  response = requests.post('https://your-backend.example.com/auth/token')
  data = response.json()['data']
  token = data['token']
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expires_in": 3600,
    "canton_party_id": "SenderInstitution::209fa2c...b341",
    "role": "institution"
  },
  "meta": {
    "request_id": "req_a1b2c3d4",
    "timestamp": "2025-03-15T09:00:00.000Z"
  }
}
```

## Using the Token

Include the token in the `Authorization` header on all subsequent requests:

<CodeGroup>
  ```bash curl theme={null}
  curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
    https://your-backend.example.com/api/v1/orders
  ```

  ```javascript fetch theme={null}
  const response = await fetch('https://your-backend.example.com/api/v1/orders', {
    headers: {
      'Authorization': `Bearer ${token}`,
    },
  });
  ```

  ```python requests theme={null}
  response = requests.get(
      'https://your-backend.example.com/api/v1/orders',
      headers={'Authorization': f'Bearer {token}'},
  )
  ```
</CodeGroup>

## JWT Claims

The token contains these claims:

| Claim             | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `sub`             | Your Canton Party ID                                                 |
| `canton_party_id` | Your Canton Party ID (same as `sub`)                                 |
| `role`            | Your participant type: `institution`, `custodian`, or `market-maker` |
| `iss`             | Token issuer: `musubi`                                               |
| `aud`             | Token audience: `musubi-api`                                         |
| `exp`             | Expiration timestamp (default: 1 hour from issuance)                 |

## Token Lifecycle

* Tokens expire after **3600 seconds** (1 hour) by default
* Request a new token before the current one expires
* Expired tokens return `401 Unauthorized`

<Warning>
  The `/auth/token` endpoint is a development convenience. In production, tokens will be issued by an external identity provider (e.g., Keycloak, Auth0) integrated with your organization's SSO.
</Warning>

## Verifying Your Identity

Use the `/api/v1/whoami` endpoint to confirm your backend's party identity, participant id, and schema version:

```bash theme={null}
curl https://your-backend.example.com/api/v1/whoami
```

```json theme={null}
{
  "data": {
    "party_id": "Institution::209fa2c...b341",
    "operator_party_id": "Musubi::1220xyz...",
    "role": "institution",
    "participant_id": "PAR::institution::1220xyz...",
    "schema_version": "v2"
  }
}
```

The `schema_version` field is pinned at `"v2"` post-ADR-0011 PR-03 — clients MUST gate on this value so any future breaking shape change is detectable, not silent. `participant_id` is the Canton participant id discovered from the Ledger API at boot; it is the empty string `""` in sandbox / localnet mode (no `MUSUBI_LEDGER_API_JWT`).
