All Documentation

API Keys & Scopes

Granular API keys with per-resource read/write permissions, modeled on Cloudflare API tokens

Overview

Every API key carries a set of scopes — permissions of the form resource:permission — and can only do what its scopes allow. A key for a soundboard app might get lines:read and sfx:read only; a build pipeline that generates dialogue might add tts:generate and lines:write. Grant only what each integration needs.

Keys authenticate the v1 REST API, the MCP server, and the Public TTS API.

Scope Catalog

write always includes read for the same resource.

ScopeGrants
projects:readList projects
characters:readList and read characters
characters:writeCreate and delete characters
voices:readList and read project voices
voices:writeCreate and delete project voices
internal_voices:readList and read Voice Studio custom voices
internal_voices:writeManage Voice Studio custom voices
external_voices:readList voice providers and their available voices
lines:readList, read, and download saved lines
lines:writeSave lines, add versions, set active version, delete
sfx:readList, read, and download saved sound effects
sfx:writeGenerate and save sound effects, add versions, delete
tts:generateGenerate speech with internal or external voices (spends tokens)

Creating and Managing Keys

  1. 1Go to API Keys and choose New API Key.
  2. 2Name the key after the integration that will hold it ("Game build pipeline", "Support bot").
  3. 3Tick the permissions it needs — one row per resource with Read/Write checkboxes. At least one is required.
  4. 4Copy the key and store it in your secret manager. Treat it like a password.

Existing keys can be disabled (temporarily blocks all use), have their permissions edited at any time (takes effect immediately), or be deleted permanently.

Legacy keys

Keys created before scopes existed behave as if they had only tts:generate — exactly what they could do before. Edit their permissions to grant more.

Using a Key

Send the key with every request, preferably in the Authorization header:

# Preferred
curl -H "Authorization: Bearer $API_KEY" https://<host>/api/v1/verify

# Also accepted
curl -H "X-API-Key: $API_KEY" https://<host>/api/v1/verify

Verifying a key

GET /api/v1/verify works with any valid key (no scope required) and returns its name, organization, and scopes — useful in health checks and for debugging permission issues:

{
  "success": true,
  "result": {
    "keyId": "…",
    "name": "Game build pipeline",
    "organizationId": "…",
    "scopes": ["tts:generate", "lines:write", "lines:read"],
    "status": "active"
  }
}

Errors and Limits

StatusMeaning
401Missing, invalid, or disabled API key
403The key works but is missing the required scope (the error names it)
402Insufficient token balance for a generation
429Rate limited — 60 requests/minute per key (Retry-After header included)

All v1 errors use the response envelope:

{ "success": false, "errors": [{ "code": "missing_scope", "message": "API key is missing the required scope: lines:write" }] }

Best Practices

Recommendations

  • • One key per integration — never share keys between apps.
  • • Grant the minimum scopes; prefer read-only keys wherever possible.
  • • Rotate by creating a new key, migrating, then deleting the old one.
  • • Disable (rather than delete) a key to investigate suspicious usage.
  • • Watch token spend in the Tokens dashboard — generation calls are attributed in the audit log.