POST
/v1/synthesize
Synthesize Russian speech and return an audio file.
Returns **binary audio** (not JSON). Set `Accept` if you prefer a specific Content-Type; otherwise `format` in the body selects it.
Example:
POST /v1/synthesize
X-Api-Key: YOUR_KEY
{
"text": "Привет! Это демонстрация синтеза русской речи.",
"voice": "preset_anna",
"format": "mp3",
"sample_rate": 24000,
"speed": 1.0,
"emotion": "neutral",
"effects": "[{\"type\": \"reverb\", \"room_size\": 0.5}]"
}
`effects` is an optional JSON-encoded string holding an array of effect
descriptors (reverb, compressor, eq, distortion, chorus, pitch, timestretch).
It requires a Pro/Business plan and is applied to the audio after synthesis,
before it is encoded into the requested format.
Errors are RFC 7807 Problem Details with a `code` field.
Request body application/json
Schema: SynthesizeRequestDto
· Required: —
| Field |
Type |
Required |
Description |
text |
string |
✓ |
Text to speak. Required. Max 5000 characters (500 on the public demo). |
voice |
string (enum) | null |
— |
Voice id. Default preset_anna. See GET /v1/voices. |
format |
string (enum) | null |
— |
Audio format: mp3 (default), wav, ogg (Vorbis), or opus (OGG/Opus). |
sample_rate |
integer (enum) | null |
— |
Sample rate in Hz: 8000, 16000, 24000 (default), 48000. |
speed |
number (float) | null |
— |
Speaking rate from 0.5 to 2.0. Default 1.0. |
pitch |
number (float) | null |
— |
Pitch from 0.5 to 2.0. Default 1.0. |
emotion |
string | null |
— |
Accepted for backward compatibility. CosyVoice does not support emotion — this value is ignored. |
ssml |
boolean | null |
— |
If true, text is treated as SSML (speak, p, s, break, prosody only). |
put_accent |
boolean | null |
— |
Accepted for backward compatibility. CosyVoice consumes plain text through
a tokenizer with no phoneme input, so stress marks cannot reach the model —
this value is ignored. Use RussianTts.Api.Contracts.SynthesizeRequestDto.Lexicon to fix the pronunciation of
individual words. |
put_yo |
boolean | null |
— |
Accepted for backward compatibility and ignored: CosyVoice consumes plain
text tokens and has no phoneme input, so the letter ё cannot be forced. |
normalize |
boolean | null |
— |
Accepted for backward compatibility and ignored: the engine already reads
digits correctly, so there is nothing to expand. |
model |
string (enum) | null |
— |
Synthesis model: standard (default, preset voices) or premium (cloned voices). Both run on CosyVoice. |
language |
string | null |
— |
Language code for multilingual synthesis (CosyVoice; defaults to the voice language). |
effects |
string | null |
— |
Optional audio-effects chain applied after synthesis. A JSON-encoded string
holding an array of effect descriptors, e.g. "[{\"type\": \"reverb\", \"room_size\": 0.5}]".
Requires a plan with audio effects enabled. Not supported for streaming synthesis. |
lexicon |
object | null |
— |
Optional pronunciation overrides applied to the engine text before synthesis
(up to 200 entries; source words are matched whole-word, case-insensitively).
Use it for abbreviations, brands and names the model would read incorrectly,
e.g. `{ "ООО": "общество с ограниченной ответственностью" }`.
Ignored for SSML requests (a replacement inside a tag would break the markup).
Quota is counted on the original text. |
Responses
| Status |
Description |
Schema |
200 |
Binary audio. Content-Type matches the requested format (mp3 → audio/mpeg, wav, ogg). |
string (binary) |
400 |
Invalid request. Body is RFC 7807 with extension field `code`. |
ErrorResponse |
401 |
Missing or invalid API key. |
ErrorResponse |
403 |
Plan does not allow this operation (streaming or premium engine). |
ErrorResponse |
413 |
Text exceeds the plan or request character limit. |
ErrorResponse |
429 |
Monthly quota exceeded, the request rate limit was hit, or the synthesis queue is saturated. See Retry-After. |
ErrorResponse |
500 |
Unexpected server error. |
ErrorResponse |
503 |
The synthesis engine is unavailable, or the premium engine was requested but is not enabled. |
ErrorResponse |
POST
/v1/synthesize/async
Start an asynchronous long-form synthesis job (audiobook / long article).
Queue a long text (up to the deployment's long-form character limit) and
get a job ID immediately. The text is split into paragraphs, each
synthesized through the standard pipeline, and the clips are concatenated
into a single sample-accurate **WAV** with a timed audiobook manifest.
Poll `GET /v1/synthesize/async/{jobId}` for the manifest, then
download the audio from `GET /v1/synthesize/async/{jobId}/audio`.
Pass `webhookUrl` as a query parameter to be notified on completion.
Parameters
| Name |
In |
Type |
Required |
Description |
webhookUrl |
query |
string |
— |
|
Request body application/json
Schema: SynthesizeRequestDto
· Required: —
| Field |
Type |
Required |
Description |
text |
string |
✓ |
Text to speak. Required. Max 5000 characters (500 on the public demo). |
voice |
string (enum) | null |
— |
Voice id. Default preset_anna. See GET /v1/voices. |
format |
string (enum) | null |
— |
Audio format: mp3 (default), wav, ogg (Vorbis), or opus (OGG/Opus). |
sample_rate |
integer (enum) | null |
— |
Sample rate in Hz: 8000, 16000, 24000 (default), 48000. |
speed |
number (float) | null |
— |
Speaking rate from 0.5 to 2.0. Default 1.0. |
pitch |
number (float) | null |
— |
Pitch from 0.5 to 2.0. Default 1.0. |
emotion |
string | null |
— |
Accepted for backward compatibility. CosyVoice does not support emotion — this value is ignored. |
ssml |
boolean | null |
— |
If true, text is treated as SSML (speak, p, s, break, prosody only). |
put_accent |
boolean | null |
— |
Accepted for backward compatibility. CosyVoice consumes plain text through
a tokenizer with no phoneme input, so stress marks cannot reach the model —
this value is ignored. Use RussianTts.Api.Contracts.SynthesizeRequestDto.Lexicon to fix the pronunciation of
individual words. |
put_yo |
boolean | null |
— |
Accepted for backward compatibility and ignored: CosyVoice consumes plain
text tokens and has no phoneme input, so the letter ё cannot be forced. |
normalize |
boolean | null |
— |
Accepted for backward compatibility and ignored: the engine already reads
digits correctly, so there is nothing to expand. |
model |
string (enum) | null |
— |
Synthesis model: standard (default, preset voices) or premium (cloned voices). Both run on CosyVoice. |
language |
string | null |
— |
Language code for multilingual synthesis (CosyVoice; defaults to the voice language). |
effects |
string | null |
— |
Optional audio-effects chain applied after synthesis. A JSON-encoded string
holding an array of effect descriptors, e.g. "[{\"type\": \"reverb\", \"room_size\": 0.5}]".
Requires a plan with audio effects enabled. Not supported for streaming synthesis. |
lexicon |
object | null |
— |
Optional pronunciation overrides applied to the engine text before synthesis
(up to 200 entries; source words are matched whole-word, case-insensitively).
Use it for abbreviations, brands and names the model would read incorrectly,
e.g. `{ "ООО": "общество с ограниченной ответственностью" }`.
Ignored for SSML requests (a replacement inside a tag would break the markup).
Quota is counted on the original text. |
Responses
| Status |
Description |
Schema |
202 |
Accepted |
SynthesisJobResponse |
400 |
Invalid request. Body is RFC 7807 with extension field `code`. |
ErrorResponse |
401 |
Missing or invalid API key. |
ErrorResponse |
403 |
Plan does not allow this operation (streaming or premium engine). |
ErrorResponse |
413 |
Text exceeds the plan or request character limit. |
ErrorResponse |
429 |
Monthly quota exceeded, the request rate limit was hit, or the synthesis queue is saturated. See Retry-After. |
ErrorResponse |
503 |
The synthesis engine is unavailable, or the premium engine was requested but is not enabled. |
ErrorResponse |
POST
/v1/synthesize/stream
Stream audio chunks as they are produced. Pro and Business plans only.
Same body as /v1/synthesize. Response is an unbuffered audio byte stream.
Free/Basic receive 403 `streaming_forbidden`. Audio effects (`effects`) are
not supported for streaming synthesis.
Request body application/json
Schema: SynthesizeRequestDto
· Required: —
| Field |
Type |
Required |
Description |
text |
string |
✓ |
Text to speak. Required. Max 5000 characters (500 on the public demo). |
voice |
string (enum) | null |
— |
Voice id. Default preset_anna. See GET /v1/voices. |
format |
string (enum) | null |
— |
Audio format: mp3 (default), wav, ogg (Vorbis), or opus (OGG/Opus). |
sample_rate |
integer (enum) | null |
— |
Sample rate in Hz: 8000, 16000, 24000 (default), 48000. |
speed |
number (float) | null |
— |
Speaking rate from 0.5 to 2.0. Default 1.0. |
pitch |
number (float) | null |
— |
Pitch from 0.5 to 2.0. Default 1.0. |
emotion |
string | null |
— |
Accepted for backward compatibility. CosyVoice does not support emotion — this value is ignored. |
ssml |
boolean | null |
— |
If true, text is treated as SSML (speak, p, s, break, prosody only). |
put_accent |
boolean | null |
— |
Accepted for backward compatibility. CosyVoice consumes plain text through
a tokenizer with no phoneme input, so stress marks cannot reach the model —
this value is ignored. Use RussianTts.Api.Contracts.SynthesizeRequestDto.Lexicon to fix the pronunciation of
individual words. |
put_yo |
boolean | null |
— |
Accepted for backward compatibility and ignored: CosyVoice consumes plain
text tokens and has no phoneme input, so the letter ё cannot be forced. |
normalize |
boolean | null |
— |
Accepted for backward compatibility and ignored: the engine already reads
digits correctly, so there is nothing to expand. |
model |
string (enum) | null |
— |
Synthesis model: standard (default, preset voices) or premium (cloned voices). Both run on CosyVoice. |
language |
string | null |
— |
Language code for multilingual synthesis (CosyVoice; defaults to the voice language). |
effects |
string | null |
— |
Optional audio-effects chain applied after synthesis. A JSON-encoded string
holding an array of effect descriptors, e.g. "[{\"type\": \"reverb\", \"room_size\": 0.5}]".
Requires a plan with audio effects enabled. Not supported for streaming synthesis. |
lexicon |
object | null |
— |
Optional pronunciation overrides applied to the engine text before synthesis
(up to 200 entries; source words are matched whole-word, case-insensitively).
Use it for abbreviations, brands and names the model would read incorrectly,
e.g. `{ "ООО": "общество с ограниченной ответственностью" }`.
Ignored for SSML requests (a replacement inside a tag would break the markup).
Quota is counted on the original text. |
Responses
| Status |
Description |
Schema |
200 |
Binary audio. Content-Type matches the requested format (mp3 → audio/mpeg, wav, ogg). |
string (binary) |
400 |
Invalid request. Body is RFC 7807 with extension field `code`. |
ErrorResponse |
401 |
Missing or invalid API key. |
ErrorResponse |
403 |
Plan does not allow this operation (streaming or premium engine). |
ErrorResponse |
413 |
Text exceeds the plan or request character limit. |
ErrorResponse |
429 |
Monthly quota exceeded, the request rate limit was hit, or the synthesis queue is saturated. See Retry-After. |
ErrorResponse |
503 |
The synthesis engine is unavailable, or the premium engine was requested but is not enabled. |
ErrorResponse |