All Documentation

REST API (v1)

The full ToneBoard API: projects, characters, voices, saved content, and audio generation — enforced by scoped API keys

Basics

Base URL: https://<host>/api/v1

Authenticate every request with a scoped API key via Authorization: Bearer <key> (or X-API-Key). Requests are rate-limited to 60/minute per key. Responses use a Cloudflare-style envelope:

// Success
{ "success": true, "result": { ... } }

// Failure (401 / 402 / 403 / 404 / 409 / 429 / 500)
{ "success": false, "errors": [{ "code": "missing_scope", "message": "..." }] }

Scopes

Each endpoint below lists its required scope. write implies read. Content endpoints resolve the scope per item: lines need lines:*, sound effects need sfx:*.

Verify

GET/api/v1/verify

No scope required. Returns the key's name, organization, and scopes. Use it in health checks.

Projects

GET/api/v1/projectsprojects:read

Lists the organization's projects: id, name, description, timestamps.

Characters

A character binds a voice to a persona (characterDefinition holds tone instructions used for text enhancement). external tells ToneBoard which kind of voice voiceId references.

GET/api/v1/characters?projectId={'{id}'}characters:read
GET/api/v1/characters/{'{id}'}characters:read
POST/api/v1/characterscharacters:write
FieldTypeDescription
name*stringDisplay name
projectId*stringProject the character belongs to
voiceId*stringInternal (Voice Studio) voice id — or a project voice id with external: true
externalbooleantrue when voiceId is a project (external provider) voice
characterDefinitionstringPersona/tone instructions used to enhance text before speaking

The referenced voice is validated against the right store before the character is created.

DELETE/api/v1/characters/{'{id}'}characters:write

Returns 409 if live endpoints still use the character.

Project Voices

GET/api/v1/voices?projectId={'{id}'}voices:read
GET/api/v1/voices/{'{id}'}voices:read
POST/api/v1/voicesvoices:write
FieldTypeDescription
name*stringYour name for the voice
projectId*stringProject to add the voice to
voiceProviderId*stringProvider connection id (see External Voices below)
externalVoiceId*stringThe provider-native voice id
DELETE/api/v1/voices/{'{id}'}voices:write

Returns 409 if characters still use the voice.

Internal Voices (Voice Studio)

GET/api/v1/internal-voicesinternal_voices:read
POST/api/v1/internal-voices/designinternal_voices:write
FieldTypeDescription
prompt*stringDescription of the desired voice

Returns requestId and preview files with temporary URLs (~1 hour). Spends the voice-creation token cost; refunded on failure.

POST/api/v1/internal-voicesinternal_voices:write
FieldTypeDescription
name*stringVoice name
requestId*stringFrom the design call
audioFileUrl*stringThe chosen preview URL from the design call
prompt*stringThe prompt the voice was designed from
descriptionstringOptional description
projectIdstringOptional project association
DELETE/api/v1/internal-voices/{'{id}'}internal_voices:write

Returns 409 if characters still use the voice.

No cloning via API

Voice cloning from arbitrary audio is dashboard-only by design.

External Voice Providers

GET/api/v1/voice-providersexternal_voices:read

The organization's provider connections (credentials are never returned).

GET/api/v1/external-voices?voiceProviderId={'{id}'}external_voices:read

Voices available from that provider account, with voice_id values usable in POST /voices.

Saved Content

Lines and sound effects with full version history. Top-level fields always mirror the active version.

GET/api/v1/content?contentType=&projectId=&characterId=lines:read | sfx:read

Unfiltered calls return only the types the key can read.

GET/api/v1/content/{'{id}'}read (by item type)
POST/api/v1/contentwrite (by contentType)

multipart/form-data: audio (WAV/MP3/OGG/FLAC/M4A/AAC/WMA, ≤50MB), name, contentType, projectId?, characterId?, textToScreen?, tags?, source?, durationMs?. Lines require project, character, and text.

POST/api/v1/content/{'{id}'}/versionswrite (by item type)

multipart/form-data: audio + optional fields. The new version becomes active.

PATCH/api/v1/content/{'{id}'}write (by item type)
FieldTypeDescription
activeVersion*integerVersion number to make active
DELETE/api/v1/content/{'{id}'}write (by item type)

Removes the record and every version's audio. Cannot be undone.

Generation

Generation spends tokens, charged up front and refunded automatically on failure. Results are uploaded to storage and returned as URLs.

POST/api/v1/ttstts:generate
FieldTypeDescription
characterId*stringThe character to speak as (internal or external voice)
text*stringWhat to say
settingsobjectOptional overrides: stability, similarityBoost, useSpeakerBoost, speed, model, pitch, volumeGain, exaggeration
saveobjectOptional { name } — also save the result as a line (requires lines:write)
POST/api/v1/sfx/generatesfx:write
FieldTypeDescription
text*stringWhat the effect should sound like
durationSeconds*numberLength in seconds (provider max applies)
promptInfluencenumber 0-1Prompt adherence vs variety (default 0.3)
loopbooleanSeamless loop
saveobjectOptional { name, projectId?, tags? } — also save to Saved Content

Generate a line and save it in one call:

curl -s https://<host>/api/v1/tts \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "characterId": "<characterId>",
    "text": "Welcome back, adventurer!",
    "save": { "name": "Welcome Back" }
  }'

Response:

{
  "success": true,
  "result": {
    "audioUrl": "https://<r2-public>/lines/<org>/<project>/<uuid>.mp3",
    "audioKey": "lines/<org>/<project>/<uuid>.mp3",
    "contentType": "audio/mpeg",
    "characterId": "…",
    "characterName": "Narrator",
    "internalVoice": false,
    "tokensCharged": 5,
    "savedContent": { "id": "…", "name": "Welcome Back", ... }
  }
}

Live-endpoint TTS

The cached, live-endpoint-driven TTS API remains at GET /api/public/tts?liveEndpointId=… (scope tts:generate) — see Public TTS API.

Token Costs

OperationCost (tokens)
TTS — external voice5
TTS — internal voice10
SFX generationper second (provider pricing)
Voice design / save (each)25