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
/api/v1/verifyNo scope required. Returns the key's name, organization, and scopes. Use it in health checks.
Projects
/api/v1/projectsprojects:readLists 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.
/api/v1/characters?projectId={'{id}'}characters:read/api/v1/characters/{'{id}'}characters:read/api/v1/characterscharacters:write| Field | Type | Description |
|---|---|---|
name* | string | Display name |
projectId* | string | Project the character belongs to |
voiceId* | string | Internal (Voice Studio) voice id — or a project voice id with external: true |
external | boolean | true when voiceId is a project (external provider) voice |
characterDefinition | string | Persona/tone instructions used to enhance text before speaking |
The referenced voice is validated against the right store before the character is created.
/api/v1/characters/{'{id}'}characters:writeReturns 409 if live endpoints still use the character.
Project Voices
/api/v1/voices?projectId={'{id}'}voices:read/api/v1/voices/{'{id}'}voices:read/api/v1/voicesvoices:write| Field | Type | Description |
|---|---|---|
name* | string | Your name for the voice |
projectId* | string | Project to add the voice to |
voiceProviderId* | string | Provider connection id (see External Voices below) |
externalVoiceId* | string | The provider-native voice id |
/api/v1/voices/{'{id}'}voices:writeReturns 409 if characters still use the voice.
Internal Voices (Voice Studio)
/api/v1/internal-voicesinternal_voices:read/api/v1/internal-voices/designinternal_voices:write| Field | Type | Description |
|---|---|---|
prompt* | string | Description of the desired voice |
Returns requestId and preview files with temporary URLs (~1 hour). Spends the voice-creation token cost; refunded on failure.
/api/v1/internal-voicesinternal_voices:write| Field | Type | Description |
|---|---|---|
name* | string | Voice name |
requestId* | string | From the design call |
audioFileUrl* | string | The chosen preview URL from the design call |
prompt* | string | The prompt the voice was designed from |
description | string | Optional description |
projectId | string | Optional project association |
/api/v1/internal-voices/{'{id}'}internal_voices:writeReturns 409 if characters still use the voice.
No cloning via API
Voice cloning from arbitrary audio is dashboard-only by design.
External Voice Providers
/api/v1/voice-providersexternal_voices:readThe organization's provider connections (credentials are never returned).
/api/v1/external-voices?voiceProviderId={'{id}'}external_voices:readVoices 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.
/api/v1/content?contentType=&projectId=&characterId=lines:read | sfx:readUnfiltered calls return only the types the key can read.
/api/v1/content/{'{id}'}read (by item type)/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.
/api/v1/content/{'{id}'}/versionswrite (by item type)multipart/form-data: audio + optional fields. The new version becomes active.
/api/v1/content/{'{id}'}write (by item type)| Field | Type | Description |
|---|---|---|
activeVersion* | integer | Version number to make active |
/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.
/api/v1/ttstts:generate| Field | Type | Description |
|---|---|---|
characterId* | string | The character to speak as (internal or external voice) |
text* | string | What to say |
settings | object | Optional overrides: stability, similarityBoost, useSpeakerBoost, speed, model, pitch, volumeGain, exaggeration |
save | object | Optional { name } — also save the result as a line (requires lines:write) |
/api/v1/sfx/generatesfx:write| Field | Type | Description |
|---|---|---|
text* | string | What the effect should sound like |
durationSeconds* | number | Length in seconds (provider max applies) |
promptInfluence | number 0-1 | Prompt adherence vs variety (default 0.3) |
loop | boolean | Seamless loop |
save | object | Optional { 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
| Operation | Cost (tokens) |
|---|---|
| TTS — external voice | 5 |
| TTS — internal voice | 10 |
| SFX generation | per second (provider pricing) |
| Voice design / save (each) | 25 |
