Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kugelaudio.com/llms.txt

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

Custom dictionaries let you control how the TTS pipeline pronounces specific words. Each dictionary is scoped to a project and contains word → replacement/IPA mappings that are applied before synthesis. Use these endpoints to sync dictionaries from your own data sources (PIM, CMS, internal glossary). The TTS-side cache is invalidated after every mutation, so the next synthesis request picks up your changes immediately.
Authentication uses your project-scoped API key. Master-key callers must supply ?project_id=<id> on every request because the master key is not pinned to a project.

List Dictionaries

Return every dictionary in the caller’s project.
GET

Query Parameters

project_id
integer
Required for master-key callers; rejected for project-scoped keys whose value disagrees with the key’s project.

Response

{
  "dictionaries": [
    {
      "id": 1,
      "project_id": 42,
      "name": "Brand names",
      "description": "Customer product names",
      "language": "en",
      "is_active": true,
      "created_at": "2026-05-20T09:00:00+00:00",
      "updated_at": "2026-05-20T09:05:00+00:00"
    }
  ]
}

Example

curl -X GET "https://api.kugelaudio.com/v1/dictionaries" \
  -H "Authorization: Bearer YOUR_API_KEY"

Create Dictionary

POST

Body

name
string
required
Display name. Must be unique within the project.
description
string
Free-form description.
language
string
BCP-47 language tag (en, de-DE, …). Omit for all languages.

Example

curl -X POST "https://api.kugelaudio.com/v1/dictionaries" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Brand names", "language": "en"}'

Get Dictionary

GET
Returns the dictionary record. Returns 403 Forbidden if the dictionary belongs to a project your API key is not scoped to.

Update Dictionary

PATCH
Only the provided fields are changed.

Body

name
string
description
string
language
string
is_active
boolean
Disable a dictionary without deleting it.

Example

curl -X PATCH "https://api.kugelaudio.com/v1/dictionaries/1" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}'

Delete Dictionary

DELETE
Deletes the dictionary and all its entries.

Response

{ "deleted": true }

List Entries

GET

Query Parameters

Case-insensitive substring filter on word.
limit
integer
default:"100"
Page size, 1-500.
offset
integer
default:"0"
Pagination offset.

Response

{
  "entries": [
    {
      "id": 11,
      "dictionary_id": 1,
      "word": "Postgres",
      "replacement": "post-gres",
      "ipa": null,
      "case_sensitive": false,
      "created_at": "2026-05-20T09:00:00+00:00",
      "updated_at": "2026-05-20T09:00:00+00:00"
    }
  ],
  "total": 12,
  "limit": 100,
  "offset": 0
}

Add Entry

POST

Body

word
string
required
Word to match (≤ 200 chars).
replacement
string
required
Text the engine pronounces instead (≤ 1000 chars).
ipa
string
Optional IPA transcription. Takes precedence over replacement when set.
case_sensitive
boolean
default:"false"
Match the original case exactly.

Example

curl -X POST "https://api.kugelaudio.com/v1/dictionaries/1/entries" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"word": "Postgres", "replacement": "post-gres"}'

Bulk Replace Entries

PUT
Atomically replace every entry in the dictionary. Entries currently in the dictionary whose word is not in the supplied list are deleted. Idempotent — calling twice with the same payload converges to the same final state.

Body

entries
array
required
Array of { word, replacement, ipa?, case_sensitive? } items. Duplicate word values within the payload are rejected.

Response

{ "upserted": 25, "deleted": 3, "total": 25 }

Example

curl -X PUT "https://api.kugelaudio.com/v1/dictionaries/1/entries" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entries": [
      {"word": "Postgres",   "replacement": "post-gres"},
      {"word": "Kubernetes", "replacement": "koo-ber-net-eez"}
    ]
  }'

Update Entry

PATCH
Only non-null fields are sent.

Body

word
string
replacement
string
ipa
string
case_sensitive
boolean

Delete Entry

DELETE

Response

{ "deleted": true }

Error responses

StatusCodeMeaning
400VALIDATION_ERRORMissing or invalid field; e.g. master-key call without project_id.
401UNAUTHORIZEDAPI key missing, invalid, or not project-scoped.
403UNAUTHORIZEDAPI key is scoped to a different project than the target.
404NOT_FOUNDDictionary or entry does not exist.