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

# Authentication

> Create a wallet session for browser requests or mint an API token for a backend, bot, or command-line client.

Public pool and token metadata do not require credentials. Most data, routing, and transaction-schema endpoints do.

Choose the credential that matches your client:

| Client               | Credential                         | Storage rule                                                   |
| -------------------- | ---------------------------------- | -------------------------------------------------------------- |
| Browser application  | Wallet session in httpOnly cookies | Let the browser manage cookies; keep the CSRF token in memory  |
| Backend, bot, or CLI | Long-lived `ss_...` API token      | Store it in a secret manager or protected environment variable |

Both flows begin with an invited wallet.

## Create a browser wallet session

<Steps>
  <Step title="Request a challenge">
    Send the wallet address to `POST /auth/challenge`.

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    curl --fail-with-body \
      "https://api.swap.shield.fi/auth/challenge" \
      --header "Content-Type: application/json" \
      --data '{"address":"aleo1..."}'
    ```

    The response contains `data.nonce` and `data.message`.
  </Step>

  <Step title="Sign the returned message">
    Ask the wallet to sign the exact UTF-8 bytes in `data.message`. Do not reconstruct, trim, or normalize the message.

    Signing proves control of the address. It does not submit a transaction or spend a token record.
  </Step>

  <Step title="Verify the signature">
    Send the address and signature to `POST /auth/verify`. The example stores the returned cookies in `session.cookies`.

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    curl --fail-with-body \
      "https://api.swap.shield.fi/auth/verify" \
      --header "Content-Type: application/json" \
      --cookie-jar session.cookies \
      --data '{"address":"aleo1...","signature":"sign1..."}'
    ```

    A successful response sets access and refresh tokens as httpOnly cookies. The JSON body returns the wallet address, access-token expiry, and a CSRF token.
  </Step>

  <Step title="Send authenticated requests">
    Include the cookie jar on subsequent requests. Add the CSRF token in `X-CSRF-Token` for state-changing session requests.

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    curl --fail-with-body \
      "https://api.swap.shield.fi/api-tokens" \
      --cookie session.cookies
    ```
  </Step>
</Steps>

Access cookies expire after 15 minutes. `POST /auth/refresh` rotates the refresh token and sets fresh cookies. If two refreshes race, one can return `409`; retry the original API request after the successful refresh completes.

## Create an API token for a backend

API-token creation requires an authenticated browser session and invited access.

```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
curl --fail-with-body \
  "https://api.swap.shield.fi/api-tokens" \
  --request POST \
  --cookie session.cookies \
  --header "Content-Type: application/json" \
  --header "X-CSRF-Token: YOUR_CSRF_TOKEN" \
  --data '{"name":"market-data-worker","expires_in_days":30}'
```

The response shows the full `ss_...` token once. Store it before closing the response. Later list responses expose only token metadata and a prefix.

Use the token as a bearer credential:

```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
curl --fail-with-body \
  "https://api.swap.shield.fi/route?token_in=TOKEN_A&token_out=TOKEN_B&amount_in=1000000" \
  --header "Authorization: Bearer ss_YOUR_API_TOKEN"
```

## Credential boundaries

* A valid wallet signature establishes wallet control, not administrator authority.
* API tokens cover data and trading endpoints. Token management and administrative endpoints require a wallet session.
* WebSocket clients can request a short-lived ticket with a browser session or API token. They must renew authentication before the 60-second ticket expires.
* Never place session cookies, CSRF tokens, or API tokens in URLs or logs.
* Revoke a backend token with `DELETE /api-tokens/{id}` when it is no longer needed.
* Use `GET /auth/sessions` and `POST /auth/sessions/{session_id}/revoke` to manage wallet sessions.
* Use `POST /auth/logout` for the current session or `POST /auth/logout-all` for every wallet session.
