Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trulayer.ai/llms.txt

Use this file to discover all available pages before exploring further.

API keys can carry an optional set of scopes that restrict what the key is allowed to do. The flagship use-case: hand an MCP server (or any LLM agent reasoning over your trace history) a query-scoped key so it can read traces, evals, and metrics but cannot ingest new spans, create feedback, or mutate any resource. If the key leaks, the blast radius is bounded to read access.

Why scopes exist

A TruLayer key without scopes carries full access to every endpoint for its tenant — the same powers the dashboard UI has. That is the right default for your backend services and SDK initialization, but it is the wrong default for:
  • MCP servers connected to Claude, Cursor, Windsurf, or any other LLM client. The server should be able to answer “show me recent failures” without being able to forge traces or revoke other keys.
  • Analytical clients and BI pipelines that only read metrics and eval results.
  • LLM agents that reason over trace history as part of their prompt context — scoping prevents prompt-injection from escalating into data mutation.
Scopes are additive: a key can carry one scope today, and future scopes (ingest, feedback-write, etc.) will be introduced the same way.

Available scopes

ScopeGrants
queryRead-only access to traces, evals, metrics, anomalies, projects, and the semantic-search endpoint. No writes, no key management, no billing.
A key may declare multiple scopes; the effective permission set is the union.

Back-compat: empty scopes = full access

Keys created before the scopes feature — and keys you create without passing any scopes — have an empty scopes array and retain their legacy full access. Only keys that explicitly declare scopes are restricted by the scope middleware. This means you can safely roll out scoped keys alongside existing integrations without touching any currently deployed service.

Creating a scoped key in the dashboard

  1. Sign in to app.trulayer.ai.
  2. Navigate to Settings → API keys.
  3. Click New Key.
  4. Give the key a descriptive name (e.g. claude-mcp-readonly).
  5. Under Scopes, select query.
  6. Click Create. Copy the displayed key — it will never be shown again.
See Dashboard — Settings → API keys for the full key-management flow, including rotation and revocation.

Creating a scoped key via the API

curl -X POST https://api.trulayer.ai/v1/apikeys \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "claude-mcp-readonly",
    "scopes": ["query"]
  }'
Response:
{
  "id": "ak_01HXYZ...",
  "name": "claude-mcp-readonly",
  "prefix": "tl_prod_4f2a",
  "scopes": ["query"],
  "secret": "tl_prod_4f2a...full-key-shown-once...",
  "created_at": "2026-04-24T10:00:00Z"
}
The secret field is returned exactly once. Store it in your secret manager immediately. Omit scopes (or pass an empty array) to create a legacy full-access key.

Using a scoped key from the SDKs

Scoped keys are ordinary bearer tokens — initialize the SDK the same way you always have.
from trulayer import TruLayer

client = TruLayer(api_key="tl_prod_4f2a...")

# Query scope: read-only endpoints work
traces = client.traces.list(limit=50)
runs = client.evals.list_runs()

# Write endpoints raise a 403 ScopeError
# client.traces.ingest(...)  # ❌ forbidden with a query-scoped key
A write call with a scope-restricted key returns HTTP 403 with error code scope_forbidden — your client should treat it like any other authorization failure.

What to do if you need write access

If an MCP tool or agent genuinely needs to write (for example, to submit feedback), create a second key with the appropriate scope rather than relaxing an existing one. Keep the read path and the write path on separate keys so you can revoke one without disrupting the other.