<!-- tempo-docs-context -->
> Source: [/docs/api/authentication](https://tempo.xyz/developers/docs/api/authentication.md)
> Section: [API reference](https://tempo.xyz/developers/docs/api.md). Tempo API reference: authentication, conventions, endpoints grouped by product, Console management endpoints, JSON-RPC, and the indexer. An API key authenticates API requests; an account signing key authorizes transactions.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

<span id="api-authentication" />

# Authentication

Choose public access, pay per request with MPP, or authenticate with an API key:

| Method | Credential | Use for |
| --- | --- | --- |
| **Public** | None | Trying the API and low-volume reads, within a per-IP [rate limit](https://tempo.xyz/developers/docs/api/rate-limits). |
| **MPP** | `Authorization: Payment <credential>` | Paying per request without a key, or continuing past a rate limit. |
| **API key** | `Authorization: Bearer tempo:sk:...` | Attributing requests to your API project with dedicated quotas. |

Most read endpoints are open to **public** (anonymous) callers, so no credential is required to get started. To raise your throughput, pay per request with [MPP](#mpp-paying-per-request) or send an **API key**. Some endpoints, such as webhook management, require a key.

:::info
Create production and sandbox API keys in [Tempo Console](https://console.tempo.xyz/?to=/\:org/api-keys). The [console API-key guide](https://tempo.xyz/developers/docs/api/console/api-keys) covers project selection, scopes, storage, rotation, and revocation.
:::

<span id="api-keys" />

## API keys

An API key grants access to API operations; it does not authorize transactions from a Tempo account. Account [access keys](https://tempo.xyz/developers/docs/accounts/access-keys) are separate signing credentials.

Every API key belongs to one of two environments, **production** or **sandbox**, that determine which chains the key may access. A key's environment is fixed when it is provisioned, and its token carries an environment-specific prefix so a leaked key is recognizable at a glance:

* Production: `tempo:sk:...`
* Sandbox: `tempo_sandbox:sk:...`

### Production and sandbox API keys

| Property | Production | Sandbox |
| --- | --- | --- |
| Token prefix | `tempo:sk:...` | `tempo_sandbox:sk:...` |
| Chains | Any chain, including mainnet and non-mainnet | Non-mainnet only, such as testnet |
| Chain selection | Defaults to mainnet when `chainId` is omitted | Pass `chainId=testnet`; mainnet requests are rejected |
| Use for | Live integrations and real data | Building and testing without touching mainnet |

Both environments support API scopes. Quotas also depend on billing state and key configuration; a sandbox project without active billing uses the public quota ceiling.

### Authenticate API requests

Send the token in either header:

```http
Authorization: Bearer tempo:sk:...
```

```http
tempo-api-key: tempo:sk:...
```

Select the chain with the `chainId` query parameter, which accepts `mainnet`, `testnet`, or a numeric chain id. When omitted, it defaults to mainnet. Pass `chainId=testnet` when using a sandbox key:

```bash
curl 'https://api.tempo.xyz/v1/blocks?chainId=testnet' \
  --header 'Authorization: Bearer tempo_sandbox:sk:...'
```

### API authentication behaviors

* A sandbox request that selects mainnet, including by omitting `chainId`, returns `403 api_key_forbidden`.
* **The plaintext token is shown only once**, at provision time. Store it securely; it cannot be revealed again. If you lose it, revoke the key and provision a new one.
* At rest, only a hash of the token is stored. Tokens are redacted from logs and error output.

### IP-restricted API keys

An API key can carry an allowlist of exact IPv4 or IPv6 addresses and CIDR ranges. When the list is non-empty, Tempo accepts the key only when the trusted client IP matches at least one entry. A missing or nonmatching client IP returns `403` with `api_key_ip_forbidden`.

A new key with an omitted or empty allowlist is unrestricted. For an existing key, sending `allowedIps: []` removes the restriction; omitting the field from an update preserves it. Updates are eventually consistent and may take a minute or more to propagate globally. See [Restrict an API key by IP address](https://tempo.xyz/developers/docs/api/console/api-keys#restrict-an-api-key-by-ip-address) for management examples and safe rollout guidance.

<span id="mpp-paying-per-request" />

## Pay per request with MPP

Endpoints that advertise [MPP](https://mpp.dev) accept pay-per-request credentials as an alternative to an API key. Use it to call those endpoints without a key, or to keep going once you exceed a rate limit.

Endpoints that require a key, such as webhook management, do not offer MPP.

Within quota these endpoints are free for keyed and anonymous callers alike. An eligible request over quota receives `402 Payment Required` instead of `429`. Eligibility depends on the endpoint and billing state; sandbox keys without active billing receive `429`. The `402` is protocol-native, not the JSON error envelope: the challenge rides the `WWW-Authenticate` header.

1. Read the challenge from the `WWW-Authenticate` header on the `402` response.
2. Settle it with an [MPP client](https://mpp.dev/quickstart/client), then retry the request with an `Authorization: Payment` credential.
3. The successful paid response carries a `Payment-Receipt` header.

```http
Authorization: Payment <credential>
```

An MPP client can reuse a valid credential when the payment method and challenge permit it. Follow the challenge rather than constructing a payment header manually.

:::info
`Authorization: Payment` (MPP) and `Authorization: Bearer` (API key) are distinct credentials. A Bearer API key is never treated as payment. Payment challenges and paid responses are never cached.
:::

## Console sign-in

To authenticate a Console session, use the [Console authentication API](https://tempo.xyz/developers/docs/api/console/authentication). These endpoints manage sign-in sessions, separate from API keys:

* <span id="createsiwechallenge" /> [Create a sign-in challenge](https://tempo.xyz/developers/docs/api/console/authentication#createsiwechallenge)
* <span id="verifysiwe" /> [Sign in with a wallet](https://tempo.xyz/developers/docs/api/console/authentication#verifysiwe)
* <span id="verifyidentity" /> [Sign in with an identity token](https://tempo.xyz/developers/docs/api/console/authentication#verifyidentity)
* <span id="logout" /> [Sign out](https://tempo.xyz/developers/docs/api/console/authentication#logout)
