Russian Text-to-Speech API: ru_RU Voice to MP3
You need to generate high-quality Russian speech (ru_RU) and save it as an MP3 from your backend or scripts. By the end of this guide, you will be able to call the Woord Text-to-Speech convert endpoint, pass ru_RU with a male voice, and reliably retrieve an MP3 URL you can store and serve in your application.
What you will build: ru_RU Text-to-Speech to MP3 via HTTP POST
This guide focuses on a single task: converting Russian text into an MP3 using the Woord Text-to-Speech API. The endpoint accepts a URL-encoded form POST and returns a JSON envelope with a direct audio URL. You will learn the required fields, optional tuning parameters, and how to handle the response to store or deliver the audio to users.
Account, access, and plan requirements
Authentication is via a Bearer token passed in the Authorization header. You obtain your API key after account creation. The Free plan cannot call this endpoint. The Starter plan is $9.99/month and includes an 8-day trial with 20,000 characters total, and a maximum of 10,000 characters per generated file. If you need more details beyond what is in this article, refer to the official docs.
Create your account here: Register. API reference lives here: Documentation.
Endpoint and HTTP contract
Endpoint: POST https://www.getwoord.com/api/convert
Auth: Authorization: Bearer YOUR_API_KEY
Content type: application/x-www-form-urlencoded (send form fields, not JSON)
Required fields:
- text: The text you want to synthesize.
- language: For Russian, use ru_RU.
- gender_voice: For Russian docs default, use male.
Optional fields:
- speakingRate: A numeric value such as 1.00 indicating default speed.
- effectsProfileId: Optional audio effects profile identifier (string). Use only if you have a specific profile to apply.
Response envelope (documented fields):
{"message":"Your audio has been created!","audio_src":"https://getwoord.s3.amazonaws.com/4273352455515882618255eaaf3c1cbdbe0.55443890.mp3","error":false}
Notes:
- audio_src is a direct URL to an MP3. Treat it as your downloadable asset. The example URL shown is a fixture; your response will include a different audio_src value.
- error is a boolean indicator. If true, do not assume audio_src is valid.
Parameter selection for ru_RU voice
This article focuses on Russian with locale code ru_RU. Use gender_voice=male to align with the documented default for this locale. For quick testing, start with a short phrase and a speakingRate of 1.00, then adjust speakingRate if you need faster or slower audio. Keep your text input under 10,000 characters per file to respect the per-file limit.
Sample text from the docs/editorial for this locale: Hello World. While that text is English, it is valid for testing the pipeline end to end. Replace it with your Russian content once you confirm your integration is working.
Quickstart: cURL request you can paste
The following request uses form-encoded parameters and includes Authorization with a Bearer token. Replace YOUR_API_KEY with your real key. The example uses ru_RU and the male voice with a default speakingRate of 1.00.
curl "https://www.getwoord.com/api/convert" \
-X POST \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data "text=Hello+World&gender_voice=male&language=ru_RU&speakingRate=1.00"
Tips that save debugging time:
- Ensure your body is application/x-www-form-urlencoded. With curl, --data will default to the correct content type.
- URL-encode your text. curl encodes spaces if you use +. For arbitrary Unicode (Russian), use a tool that handles percent-encoding or pass --data-urlencode for safety.
- Do not send JSON in the body. The endpoint expects form fields.
Python example: POST form fields and parse audio_src
This Python sample posts the required form fields, checks the response, and extracts the audio_src field you will store or serve. Values are illustrative.
import os
import sys
import json
import requests
API_URL = "https://www.getwoord.com/api/convert"
API_KEY = os.getenv("WOORD_API_KEY", "YOUR_API_KEY")
def synthesize_ru(text, speaking_rate="1.00", effects_profile=None):
headers = {
"Accept": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
data = {
"text": text,
"gender_voice": "male", # docs default for ru_RU
"language": "ru_RU",
"speakingRate": speaking_rate,
}
if effects_profile:
data["effectsProfileId"] = effects_profile
resp = requests.post(API_URL, headers=headers, data=data, timeout=60)
resp.raise_for_status()
payload = resp.json()
# Expected envelope (values are illustrative):
# {"message":"Your audio has been created!","audio_src":"https://...mp3","error":false}
if payload.get("error"):
raise RuntimeError(f"TTS error: {payload.get('message', 'unknown error')}")
audio_url = payload.get("audio_src")
if not audio_url:
raise RuntimeError("No audio_src returned in response.")
return audio_url, payload.get("message")
if __name__ == "__main__":
# Replace with your Russian text. Keep under 10,000 characters per file.
text = "Привет, это проверка синтеза речи на русском языке."
try:
audio_url, message = synthesize_ru(text, speaking_rate="1.00")
print("Message:", message)
print("Audio URL:", audio_url)
# You can now download and cache the MP3 using requests.get(audio_url).
except Exception as e:
print("Failed to synthesize:", e, file=sys.stderr)
sys.exit(1)
Understanding the response: fields you actually need
Here is a representative JSON response with the officially documented fields (values are illustrative):
{
"message": "Your audio has been created!",
"audio_src": "https://getwoord.s3.amazonaws.com/4273352455515882618255eaaf3c1cbdbe0.55443890.mp3",
"error": false
}
What you will use:
- audio_src: Direct link to the generated MP3. Download it server-side and store it in your own storage if you need long-term access or CDN control.
- message: Helpful for logs. Do not parse it for state; treat it as informational.
- error: A boolean indicator; if true, do not use audio_src and handle the error path in your application.
Encoding text correctly for form posts
Because the endpoint requires URL-encoded form fields, ensure you handle Unicode safely for Russian text. For curl, you can use --data-urlencode "text=...". In Python requests, passing data= with a Unicode string will be encoded as application/x-www-form-urlencoded; the library handles percent-encoding. Always verify your end-to-end path (source encoding, request builder, server) preserves your Cyrillic content.
Example with curl-safe encoding for Russian text:
curl "https://www.getwoord.com/api/convert" \
-X POST \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode "text=Привет, мир" \
--data "gender_voice=male" \
--data "language=ru_RU" \
--data "speakingRate=1.00"
Tuning speakingRate and optional effectsProfileId
If your audio sounds too fast or slow, adjust speakingRate. While this guide uses 1.00 as the default, you can experiment to find the right pacing for your content. Keep the value as a string or numeric that the form body can carry (e.g., 0.90, 1.10). For effectsProfileId, only include it if you have a known profile to apply—omit it otherwise to avoid unexpected transformations.
Handling production concerns: caching, retries, and file limits
Download and cache your MP3. The response gives you a direct S3 URL via audio_src. For predictable availability and bandwidth, fetch the file once server-side and store it in your own bucket or local cache, then serve it via your CDN. Avoid hotlinking the fixture URL from docs; your integration should use the unique URL returned for each request.
Retries and idempotency. Synthesis is a state-changing operation that creates a new file. If you retry a failed request, you may generate multiple outputs for the same text. Prefer an application-level deduplication strategy: compute a stable hash of the inputs (text, language, gender_voice, speakingRate, effectsProfileId) and check your cache before calling the API.
Input size. Keep each text input under 10,000 characters per file. If you have long scripts, split them into segments and synthesize each part. Maintain the same parameter set across segments to keep the voice consistent.
Throughput planning. The trial is 20,000 characters over 8 days. For higher throughput or volume, plan capacity by characters rather than number of files. If you expect spikes, pre-generate content that doesn’t change often and serve it from your storage to minimize on-demand conversions.
JavaScript (Node.js) example with fetch and FormData
This example shows how to submit form data and read the audio_src field using native fetch. Run it in Node 18+ or any environment with fetch and FormData available.
import process from "node:process";
const API_URL = "https://www.getwoord.com/api/convert";
const API_KEY = process.env.WOORD_API_KEY || "YOUR_API_KEY";
async function synthesizeRussian(text, speakingRate = "1.00", effectsProfileId = null) {
const form = new URLSearchParams();
form.set("text", text);
form.set("gender_voice", "male"); // docs default for ru_RU
form.set("language", "ru_RU");
form.set("speakingRate", String(speakingRate));
if (effectsProfileId) form.set("effectsProfileId", effectsProfileId);
const resp = await fetch(API_URL, {
method: "POST",
headers: {
"Accept": "application/json",
"Authorization": `Bearer ${API_KEY}`,
// fetch sets Content-Type automatically for URLSearchParams
},
body: form,
});
if (!resp.ok) {
const body = await resp.text().catch(() => "");
throw new Error(`TTS request failed: ${resp.status} ${resp.statusText} ${body}`);
}
const json = await resp.json();
if (json.error) {
throw new Error(`TTS returned error: ${json.message || "unknown"}`);
}
if (!json.audio_src) {
throw new Error("No audio_src in response.");
}
return json.audio_src;
}
// Example usage
synthesizeRussian("Это тестовое сообщение для синтеза речи на русском языке.")
.then((url) => {
console.log("Audio URL:", url);
// Download and cache the MP3 here.
})
.catch((err) => {
console.error(err);
process.exit(1);
});
Testing strategy for ru_RU content
Start with short sentences and verify intelligibility at different speakingRate values. Combine punctuation to control phrasing; periods and commas can influence pause timing. If your text includes numerals or acronyms, consider writing out words in Russian for clarity where needed. Keep your per-file content under 10,000 characters, especially if you are batch-generating long-form articles.
Operational checklist
- Authentication: Use Authorization: Bearer YOUR_API_KEY in every request.
- Encoding: Use form fields (application/x-www-form-urlencoded); do not send JSON in the request body.
- Locale: language=ru_RU.
- Voice: gender_voice=male (docs default for this locale).
- Optional tuning: speakingRate=1.00 to start; add effectsProfileId only if you need a specific profile.
- Limits: 10,000 characters per file; trial is 8 days and 20,000 characters.
- Output handling: Read audio_src from the JSON response; download and cache the MP3 on your side.
End-to-end example combining all steps
1) Build the request
Construct a form-encoded body with text, gender_voice, language, and optional speakingRate. Confirm text length and encoding before sending.
2) Send the request
POST to https://www.getwoord.com/api/convert with Accept: application/json and your Bearer token. Handle non-2xx responses by logging status and body text for troubleshooting.
3) Process the response
Parse JSON. If error is true, do not continue; capture message for your logs. Otherwise, extract audio_src and immediately download and store the MP3 in your own storage. Retain a mapping of input hash to stored file URL.
4) Serve audio
In your app, return your stored audio URL to clients. This avoids repeated conversions and gives you control over caching headers and CDN behavior.
Reference: official curl snippet and envelope
The following snippet and response envelope are from the official docs catalog for this locale and endpoint (be sure to replace YOUR_API_KEY with your actual key when you run it):
curl "https://www.getwoord.com/api/convert" -X POST -H "Accept: application/json" -H "Authorization: Bearer YOUR_API_KEY" --data "text=Hello+World&gender_voice=male&language=ru_RU&speakingRate=1.00"
{"message":"Your audio has been created!","audio_src":"https://getwoord.s3.amazonaws.com/4273352455515882618255eaaf3c1cbdbe0.55443890.mp3","error":false}
Troubleshooting tips
- Got a non-JSON response? Verify Accept: application/json and check that you are not sending JSON in the request body.
- Seeing authentication errors? Confirm you are using Authorization: Bearer YOUR_API_KEY and that your plan allows access to the endpoint.
- File exceeds limit? Split your content to keep each request under 10,000 characters.
- Inconsistent phrasing? Adjust speakingRate slightly and tune your punctuation for natural pauses.
FAQ
Can the Free plan call the convert endpoint?
No. The Free plan cannot call this endpoint. Use the Starter plan or higher.
What locale and voice should I use for Russian?
Use language=ru_RU and gender_voice=male to match the documented default for this locale.
How large can my text be?
Up to 10,000 characters per file. For longer content, split into multiple requests and stitch or serve as a playlist.
What response fields do I need to parse?
Parse audio_src for the MP3 URL and check error. message is useful for logs.
Should I store the returned audio or hotlink it?
Download the MP3 from audio_src and store it in your own storage. This gives you predictable availability and CDN control.
Ready to implement ru_RU Text-to-Speech in your stack? Create your account here: Register. For parameters and envelope details, see the Documentation.
