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

# Authentication

> Authenticate with a tenant-bound API key and grant direct-route or Treasury access.

The Wayex API authenticates with an **API key**. Send it on every request in either header:

```bash theme={null}
# Preferred
Authorization: Bearer YOUR_API_KEY

# Or
X-Api-Key: YOUR_API_KEY
```

## Key types

| Prefix | Type                | Use                                                                                                                                       |
| ------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `sk_…` | **Secret key**      | Server-side only. Works on every endpoint; required for value-affecting writes. Never expose it in a browser, mobile app, or public repo. |
| `pk_…` | **Publishable key** | Read-only, and accepted only on a small set of read endpoints (listed below).                                                             |

Publishable keys work on live rates (`GET /v1/rates`), the activity feed (`GET /v1/activity`),
your fee schedule (`GET /v1/developer-fees`), and revenue reports (`GET /v1/revenue`,
`GET /v1/reports/revenue`). Every other endpoint — including all other reads — requires a secret
key and returns `403 secret_key_required` when called with a publishable key.

<Warning>
  Treat your secret key like a password. If a key is exposed, rotate it immediately from the console
  (**Developers → API keys**). Wayex will never ask you for your secret key.
</Warning>

## Tenant binding

Every API key belongs to one tenant account. Its requests can read and change only that account's
customers, wallet, configuration, webhooks, and reporting.

Create and store credentials separately for every tenant account. Choose the credential before
making a request; the key determines the account for every Treasury call. Never reuse an
idempotency key across separate credential stores.

## Roles

Each key is bound to a **role** that scopes what it can do. Reads are available to your role's scope.
**Value-affecting** writes — creating a customer, a payment route, or a webhook subscription, or
submitting a Treasury wallet operation — require a secret key with write access.

API key creation, rotation, restriction, and revocation additionally require a recent
second-factor (MFA) confirmation, so manage keys from the console (**Developers → API keys**).
A key-management request authenticated only with an API key returns `403 step_up_required`.

## Scopes and key restrictions

Scopes are optional, per-key restrictions granted per resource family. The families are
`customers`, `routes`, `transfers`, `treasury`, `webhooks`, `fees`, `keys`, `team`, and
`settings`, each with `:read` and `:write`, plus `rates:read`. Within a family,
`<family>:write` implies `<family>:read`.

`team:write` (inviting a teammate) is a **credential-issuing** action, like API key management
above — it always requires a signed-in console admin with a fresh second factor, so a bare API
key can hold the scope but can never satisfy the request on its own.

A key created without a scope list keeps its full role-implied access. A scoped key can call only
endpoints in the families it holds, so include every family your integration uses — for example
`rates:read` if you fetch live rates, as in the example below. A request outside a scoped key's
grants returns `403 insufficient_scope`, and the error message names the scope the route requires.

### Treasury scopes

| Scope            | Access                                                                                                                                                                                             |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `treasury:read`  | Treasury overview, effective account settings, balances, funding, beneficiaries, payouts, withdrawals, conversions, and transaction history.                                                       |
| `treasury:write` | Funding-instrument and beneficiary creation, Sumsub evidence handoff, AUD payouts, stablecoin withdrawals, conversion quotes and conversion acceptance. Write access implies Treasury read access. |

### Network binding

A key may optionally carry an `allowedIps` list of IP addresses or CIDR blocks (IPv4 or IPv6; a
bare address means a single host). Set it at key creation or rotation, or via
`PATCH /v1/api-keys/{id}` — passing `null` clears the restriction, and a rotated key inherits the
retiring key's scopes and allowed IPs unless you override them.

Requests presented from outside those networks return `403 ip_not_allowed`; a request whose source
network cannot be determined is also refused. Keys without `allowedIps` are callable from anywhere.

<Note>
  Direct-route transfers are recorded automatically when a customer funds a payment route. Treasury
  is different: you create payouts, withdrawals and quoted wallet conversions against a prefunded
  wallet owned only by the authenticated tenant account. See the [Treasury
  overview](/treasury/overview) and [API reference](/api-reference/overview).
</Note>

## Example request

```bash theme={null}
curl "https://api.sandbox.rails.wayex.com/v1/rates?source=aud&destination=usdc" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

An unauthenticated or invalid request returns `401`. See [Errors](/errors) for the full error shape.
