> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Authentication

Every request to the Openfort API carries a **Bearer token** in the `Authorization` header:

```bash
Authorization: Bearer <your-key-or-token>
```

Which credential you send depends on **where the call runs** (your server or a client) and **what it acts on** (your project or a specific user). Requests with a missing, malformed, or wrong-mode credential return [`401 Unauthorized`](https://www.openfort.io/docs/api-reference/errors).

## API keys

Your project has two keys, both in the [dashboard](https://dashboard.openfort.io):

| Key | Format | Use from | For |
| --- | --- | --- | --- |
| **Publishable key** | `pk_test_…` / `pk_live_…` | Client (browser, app, game) | Client-safe SDK operations. Safe to ship. |
| **Secret key** | `sk_test_…` / `sk_live_…` | Your server only | Server-to-server operations. |

:::warning
Never expose a **secret key** in client-side code or a public repository — it can create and move funds on your account. If one leaks, roll it in the dashboard.
:::

## Test and live mode

A key's prefix fixes its environment, and test and live data are fully isolated:

* **Test keys** (`pk_test_…`, `sk_test_…`) operate on **testnet** chains.
* **Live keys** (`pk_live_…`, `sk_live_…`) operate on **mainnet** chains.

Build against test keys, then switch the prefix to go live.

## Authentication methods

Openfort accepts five credential types. Pick the one that matches the caller.

### Secret key — server-to-server

Your backend authenticates as the project with the secret key alone:

```bash
curl https://api.openfort.io/v1/transaction_intents \
  -H "Authorization: Bearer sk_test_..."
```

### Publishable key — client SDK

Client-safe endpoints (used by the Openfort SDKs) authenticate with the publishable key:

```bash
curl https://api.openfort.io/v1/... \
  -H "Authorization: Bearer pk_test_..."
```

### Player access token — act as a signed-in user

To act on behalf of a user Openfort manages, add the user's session token in `x-player-token`:

```bash
curl https://api.openfort.io/v1/... \
  -H "Authorization: Bearer pk_test_..." \
  -H "x-player-token: <user-session-jwt>"
```

### Third-party auth — verify a user from your own provider

Bring your own auth. Send the publishable key, the provider name, and the provider's token:

```bash
curl https://api.openfort.io/v1/... \
  -H "Authorization: Bearer pk_test_..." \
  -H "x-auth-provider: firebase" \
  -H "x-player-token: <provider-token>"
```

Supported providers include `firebase`, `supabase`, `accelbyte`, `lootlocker`, `playfab`, `oidc`, and `custom`.

### Auth session token — Openfort-managed auth (v2)

Endpoints under `/iam/v2` take the user's session token as the Bearer credential, plus your publishable key in `x-project-key`:

```bash
curl https://api.openfort.io/iam/v2/... \
  -H "Authorization: Bearer <session-token>" \
  -H "x-project-key: pk_test_..."
```

## Secret key scopes

A secret key also carries **scopes** — the set of operations it is allowed to perform. Scopes apply to secret keys only; publishable keys and user tokens are not scoped. Manage them from the [dashboard](https://dashboard.openfort.io).

| Resource | Scopes | Covers |
| --- | --- | --- |
| Accounts | `accounts:read`, `accounts:write`, `accounts:delete`, `accounts:sign`, `accounts:import`, `accounts:export` | Wallets under `/v2/accounts`, including backend wallets and key export. |
| Transactions | `transactions:read`, `transactions:write` | Transaction intents and gas estimation. |
| Policies | `policies:read`, `policies:write`, `policies:delete` | Gas policies and policy evaluation. |
| Fee sponsorship | `fee_sponsorship:read`, `fee_sponsorship:write`, `fee_sponsorship:delete` | Fee sponsorship configuration. |
| Contracts | `contracts:read`, `contracts:write`, `contracts:delete` | Registered contracts and contract reads. |
| Sessions | `sessions:read`, `sessions:write` | Session keys and session signatures. |
| Users | `users:read`, `users:write`, `users:delete` | Users and their wallets. |
| Backend wallet secrets | `api_key:write`, `api_key:rotate`, `api_key:delete` | Registering, rotating, and revoking backend-wallet secrets. |
| Share export | `share:export` | Exporting an account's key share. |

A key created without an explicit scope list gets a default set covering every scope above **except** `api_key:write`, `api_key:rotate`, `api_key:delete`, and `share:export`. Grant those four explicitly if you need them.

Calling an endpoint with a key that lacks a required scope returns [`403 Forbidden`](https://www.openfort.io/docs/api-reference/errors) — the key itself is valid, so re-authenticating won't help:

```json
{
  "error": {
    "type": "invalid_request_error",
    "message": "This API key does not have the required permissions for this endpoint."
  }
}
```

:::tip
The **Try** panel on each endpoint page lets you send a real request with your own key.
:::
