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

# Authentication and limits

> Use Tayho API keys safely and respond correctly to scopes, restrictions, and quota limits.

# Authentication and limits

Tayho operators issue API keys on request. There is no public key-creation endpoint or end-user key
management workflow in the MVP.

## Key kinds

Publishable keys use the `th_pk_` prefix. They may be embedded in a browser application only when
the key has an exact origin allowlist and conservative quotas. A publishable key is an application
identifier with policy—not a substitute for wallet authorization.

Secret keys use the `th_sk_` prefix and must remain on a trusted server. Never include one in a
browser bundle, mobile binary, repository, documentation example, or client-visible log.

Send either kind in a header:

```http theme={null}
X-API-Key: th_pk_example
```

The header is required for all `/v1` REST operations. Realtime WebSockets use a single-use ticket
derived from the key instead of sending the key during the upgrade.

## Scopes

| Scope            | Grants                                                                         |
| ---------------- | ------------------------------------------------------------------------------ |
| `read`           | Indexed reads, live unsigned reads, simulation, and batch reads                |
| `realtime`       | Creation of short-lived WebSocket tickets                                      |
| `actions:submit` | Relayed actions and intents, cancellations, lists, and protected receipt reads |

Every generated REST operation shows `x-tayho-required-scope` and its quota class. A key with the
wrong scope fails with `403`; retrying the same key cannot fix it.

Keys can also be restricted by deployment environment, browser origin, source CIDR, status, and
expiry. Requests fail closed when a restriction cannot be satisfied.

## Quota classes

Projects maintain separate per-minute budgets:

* `read` for indexed reads;
* `live` for RPC-backed calculations and action preparation reads;
* `realtime` for new WebSocket connections; and
* `submit` for relayed write intake and cancellation.

Admission is checked at project, key, and IP levels. Additional controls can limit wallet activity,
pending actions, per-transaction sponsored gas, and daily sponsored gas. Your issued project
configuration determines the actual values; there is no universal public numeric limit.

## Rate-limit response

When admission rejects a request, expect HTTP `429` with:

```http theme={null}
Retry-After: 60
X-RateLimit-Limit: 120
X-RateLimit-Scope: project
X-Request-ID: request-12345678
```

Wait for at least `Retry-After`, add jitter, and avoid parallel retries. The limit header describes
the rejecting budget, not necessarily every budget applied to the request.

For signed writes, reuse the same prepared SDK object or the exact same body and idempotency key.
For realtime, keep one shared subscription per application context and allow the SDK reconnect
loop to create a fresh ticket.

## Authentication failures

|  HTTP | Typical cause                                                | Response                                 |
| ----: | ------------------------------------------------------------ | ---------------------------------------- |
| `401` | Invalid, expired, or revoked key                             | Obtain a valid active key                |
| `403` | Suspended project, wrong scope, origin, CIDR, or environment | Correct the key policy or request origin |
| `429` | Project, key, IP, wallet, or action budget exhausted         | Respect `Retry-After`                    |
| `503` | Authentication or admission dependency unavailable           | Retry safe work with backoff             |

Include `x-request-id`, method, path template, status, and error code when requesting support. Never
include the API key, receipt capability, wallet signature, or full signed payload.
