Skip to content

API Overview

Tundra exposes a REST API at /api/v1/. The API is spec-first — proto/openapi.yaml is the canonical source of truth.

https://panel.example.com/api/v1

After logging in via POST /api/v1/auth/login, a tundra_session HttpOnly cookie is set automatically. All subsequent requests from the browser use this cookie.

Authorization: Bearer tnd_prod_<token>

Generate tokens in Settings → API Tokens or POST /api/v1/operators/me/tokens.

Token format: tnd_{env}_{32-byte-base64url}. Only the SHA-256 hash is stored server-side — the plaintext is shown once at creation.

All errors return a consistent envelope:

{
"error": {
"code": "resource.verb",
"message": "Human-readable description",
"request_id": "req_01j4k5m6n7p8q9r0",
"details": {}
}
}

Common error codes:

CodeHTTPMeaning
auth.unauthenticated401No valid session or token
auth.forbidden403Authenticated but insufficient role
auth.step_up_required403Step-up re-authentication needed
resource.not_found404Resource doesn’t exist
resource.conflict409Duplicate or state conflict
validation.invalid422Request body validation failed
server.internal500Internal server error

List endpoints return cursor-based pagination:

{
"data": [...],
"next_cursor": "eyJpZCI6IjAxajRr...",
"has_more": true
}

Pass ?cursor=<next_cursor> to fetch the next page. ?limit=N controls page size (default 20, max 100).

The API applies per-session and per-token rate limits. Responses include:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1714000000

When exceeded: 429 Too Many Requests with a Retry-After header.