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

# Authentication

> Keys and read tokens

API keys authorize requests within a partner account. Send `Authorization: Bearer <key>`; [SSE](/api/sse) uses a query parameter.

## Key types

Server keys (`fn_`) are backend secrets. They access partner endpoints, including history, webhooks, affiliate management and claims, and standing addresses.

Client keys (`fnp_`) can run in browsers and mobile apps. Scopes restrict their access; history, webhook management, and affiliate management and claims require server keys. Affiliate reporting permits a client key pinned to that affiliate with `affiliates:read`. See [Rate limits](/api/rate-limits) for defaults and partner overrides.

Find keys under API Keys in the [dashboard](https://orchestra.flashnet.xyz/dashboard). When account approval is enforced, pending or rejected accounts receive a 403.

## Scopes

Client keys carry scopes. A request outside the key's scopes returns `403 scope_required`; a request to an endpoint client keys can never reach returns `403 forbidden`.

* `orders:quote`: create quotes.
* `orders:submit`: submit orders.
* `orders:onramp`: create Lightning onramps.
* `orders:read`: read status.
* `orders:sse`: stream status.
* `accumulation:create`: create or reindex legacy accumulation addresses.
* `liquidation:create`: create legacy liquidation addresses.
* `affiliates:read`: read the pinned affiliate's reporting.

## Origin rules

Each client key has a mode. `server` ignores the `Origin` header. `browser` requires `Origin` and it must match the key's allowed origins, else `403 origin_required` or `403 origin_not_allowed`. `both` checks `Origin` only when present. An empty allowed-origins list accepts any origin. Global CORS applies on top.

## Read-tokens

Client reads also require a `readToken`, bound to the partner, issuing key, and one identifier for 24 hours:

* `/quote` returns a quote-bound token. Poll `/status?quoteId=QUOTE_ID` with it.
* `/submit` and `/onramp` return order-bound tokens. Use the matching `id` for status or SSE.

Status accepts `X-Read-Token` or `?readToken=`; direct client SSE accepts only the query parameter and requires an order-bound token. A quote token cannot authorize an order-ID stream. Keep polling by quote ID or use an authorized backend proxy. Server-key reads do not require a read token.

Missing tokens return `403 read_token_required`; expired or mismatched tokens return `403 invalid_read_token`.

## Other rules

* Field restrictions are endpoint-specific. Quote, onramp, and accumulation creation reject forbidden client fee fields with `403 client_key_fee_fields_forbidden`; other privileged fields may be stripped. Follow each endpoint's schema.
* When browser verification is enabled for submit or onramp, send the Turnstile token in `cf-turnstile-response`. Missing or rejected tokens return `403 turnstile_required` or `403 turnstile_failed`.
* A quote is bound to the partner that created it. Only a key from the same partner can submit it. Quotes created without `Authorization` cannot be submitted.
* Disable or revoke keys in the dashboard.

## Examples

Quote from your backend with a server key:

```bash theme={null}
curl -X POST "https://orchestration.flashnet.xyz/v1/orchestration/quote" \
  -H "Authorization: Bearer SERVER_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{
    "sourceChain": "base",
    "sourceAsset": "USDC",
    "destinationChain": "spark",
    "destinationAsset": "BTC",
    "amount": "50000000",
    "recipientAddress": "RECIPIENT_ADDRESS"
  }'
```

<Info>
  Replace `SERVER_KEY` with your `fn_...` key. Use a new `X-Idempotency-Key` for each operation and reuse it when retrying that same request. Amounts are integer strings in the asset's smallest unit: `"100000"` is 0.001 BTC; `"50000000"` is 50 USDC on Base. Read each asset's `decimals` from `/routes`.
</Info>

The same quote from a browser with a client key in `browser` mode; the response includes `readToken`:

```bash theme={null}
curl -X POST "https://orchestration.flashnet.xyz/v1/orchestration/quote" \
  -H "Authorization: Bearer CLIENT_KEY" \
  -H "Origin: https://app.example.com" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{
    "sourceChain": "base",
    "sourceAsset": "USDC",
    "destinationChain": "spark",
    "destinationAsset": "BTC",
    "amount": "50000000",
    "recipientAddress": "RECIPIENT_ADDRESS"
  }'
```
