Terms of provision

1. Get an access token

The Standard TTS API requires an access token (64 characters). After you create an account, you can get it from the settings page.

  1. Sign up for / log in to Ondoku
  2. Open the access token page
  3. Copy the 64-character string shown in the "Access token" field

Keep it secret: Do not share your access token with anyone. A third party who has it can use the service as you. If it leaks, you can reissue it on the settings page.

The samples on this page assume the token is stored in the environment variable ONDOKU_TOKEN.

2. Endpoint and request

POST https://ondoku3.com/text_to_speech_api/

Headers

HeaderValue
Content-Typeapplication/json
tokenAccess token (64 characters)

Body (JSON)

All 4 fields are required. If any of them is missing, the API returns HTTP 400.

FieldTypeRequiredDescription
voicestringRequiredVoice ID (e.g. en-US-JennyNeural). See the voice list
textstringRequiredText to read aloud (must not be empty)
speednumberRequiredSpeed (valid range: 0.3 to 4.0, e.g. 1.0). Out-of-range values are treated as the default 1.0
pitchnumberRequiredPitch (valid range: -20 to 20, e.g. 0.0). Out-of-range values are treated as the default 0

Response

On success, the API returns application/json with the URL of the generated audio and the history ID. Fetch the MP3 binary from url.

{
  "text": "Hello, this is Ondoku.",
  "url": "https://storage.googleapis.com/ondoku3/voice/...",
  "pk": 12345,
  "share": 1
}
FieldTypeDescription
textstringThe text that was read aloud
urlstringURL of the generated audio file, without the query string
pknumberID of the generation history entry (Sentence)
sharenumberShare flag. Usually 1; 0 for some error audio

On failure, the API usually returns JSON {"error": "..."}. Only rate-limit responses also include reset_in.

Notice responses that are not HTTP errors: In some cases, such as when your monthly character allowance is insufficient, the API returns HTTP 200 with JSON in the same shape as above, and url points to a notice audio file. Do not judge success by the HTTP status alone; also check the returned text / url.

3. Sample code

curl -X POST https://ondoku3.com/text_to_speech_api/ \
  -H "Content-Type: application/json" \
  -H "token: $ONDOKU_TOKEN" \
  -d '{
    "voice": "en-US-JennyNeural",
    "text": "Hello, this is Ondoku.",
    "speed": 1.0,
    "pitch": 0.0
  }' \
  | tee response.json
curl -L "$(jq -r .url response.json)" -o output.mp3
import os
import requests

resp = requests.post(
    "https://ondoku3.com/text_to_speech_api/",
    headers={
        "Content-Type": "application/json",
        "token": os.environ["ONDOKU_TOKEN"],
    },
    json={
        "voice": "en-US-JennyNeural",
        "text": "Hello, this is Ondoku.",
        "speed": 1.0,
        "pitch": 0.0,
    },
    timeout=60,
)
resp.raise_for_status()

data = resp.json()
mp3 = requests.get(data["url"], timeout=60).content
with open("output.mp3", "wb") as f:
    f.write(mp3)
print(f"saved: output.mp3 ({len(mp3)} bytes), pk={data['pk']}")
import { writeFile } from "node:fs/promises";

const token = process.env.ONDOKU_TOKEN!;

const res = await fetch("https://ondoku3.com/text_to_speech_api/", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    token,
  },
  body: JSON.stringify({
    voice: "en-US-JennyNeural",
    text: "Hello, this is Ondoku.",
    speed: 1.0,
    pitch: 0.0,
  }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);

type StandardTTSResponse = {
  text: string;
  url: string;
  pk: number;
  share: number;
};

const data = (await res.json()) as StandardTTSResponse;
const audioRes = await fetch(data.url);
if (!audioRes.ok) throw new Error(`audio HTTP ${audioRes.status}: ${await audioRes.text()}`);
const buf = Buffer.from(await audioRes.arrayBuffer());
await writeFile("output.mp3", buf);
console.log(`saved: output.mp3 (${buf.byteLength} bytes), pk=${data.pk}`);

4. Errors and notice responses

HTTPExampleCause
200{"text": "...", "url": "...", "pk": ..., "share": ...}Notice audio JSON, for example when characters are insufficient. Check the audio at url
400Token does not existsThe token header is missing or is not 64 characters
400Token does not matchInvalid token
400voice parameter is requiredvoice is missing or is not a string
400Unsupported voice requested.The voice is not in the voice list
400Please set "voice", "speed", "pitch", "text"One of the 4 required fields is missing
400"speed" and "pitch" must be finite numbersspeed / pitch is NaN or Infinity
429Rate limit exceededMore than 30 requests in 60 seconds (per client IP address)
500Internal server errorServer-side error (retry after a while)

5. Rate limits and quotas

For plan details and prices, see the pricing page.

6. Usage notes

Managing your access token

Handling of input text and generated audio

Retry guidelines

HTTPWhat to do
429 (Rate limit)Wait reset_in seconds from the response, or at least 2 seconds, then retry
5xxExponential backoff (1 second → 2 seconds → 4 seconds → 8 seconds, up to 3 times)
4xx (such as 400; authentication errors are also 400)Do not retry. Fix the request
Network timeoutRetry up to 2 to 3 times. The same text and voice return the same audio

Concurrency

Recommended timeouts

CORS (calling directly from a browser)

Content policy

The following uses are prohibited:

See the Terms of Service for details.

Copyright and commercial use of generated audio

7. SLA (uptime)

Ondoku's official APIs provide the following monthly uptime as their SLA. The definitions in this section (how uptime is measured, what is excluded, and what happens if the SLA is missed) apply to both APIs.

APIEndpointSLA (monthly uptime)
Standard TTS APIPOST /text_to_speech_api/99.0%
Advanced TTS API (Beta)POST /api/advanced-tts/
GET /api/advanced-tts/jobs/{job_id}/
98.0%

The SLA covers uptime only, not response time.

How uptime is measured

Not counted as downtime

If the SLA is missed

8. Changelog

Breaking changes (removing fields, changing types or meaning, retiring endpoints, and so on) are announced in this section 30 days before they take effect. Notable backward-compatible changes such as new fields or voices are also recorded in this section after release (no advance notice). Urgent security fixes are an exception.

DateChange
2026-10-02Started the rule of announcing breaking changes in this section 30 days in advance. Added the Advanced TTS API (Beta, 98.0% monthly uptime) to the SLA section
2026-10-01Set an SLA (99.0% monthly uptime) as an official API

9. Before contacting support

If you run into a bug or unexpected behavior, try the following first:

  1. Check the error or notice: look it up in the Errors and notice responses table
  2. Retry: it may be a temporary network or server-side error
  3. Check your remaining characters: see your monthly usage on the settings page
  4. Test with a minimal payload: check whether {"voice":"en-US-JennyNeural","text":"Test","speed":1.0,"pitch":0.0} returns 200
  5. Reissue the token: if authentication errors persist, issue a new token on the settings page

If that does not solve it, contact us through the contact form. Including the following information helps us reproduce the issue:

About specification changes: API specification changes are recorded in the Changelog. Breaking changes are announced 30 days before they take effect.