Back to Text to Speech API

API documentation

Text to Speech API

Use GET /voices to discover every language and voice currently installed on the server. Then POST /generate-speech with text, a BCP 47 language code such as en-US, hr-HR, or mk-MK, and optionally a voice ID returned by the catalog. If voice is omitted, the service chooses the highest-priority local voice for that language. English defaults to piper:en-us-lessac-medium, Croatian to rhvoice:karmela, and Macedonian to rhvoice:suze. Other installed RHVoice voices are preferred before the broad eSpeak NG fallback. Audio is generated on this server, converted to MP3, and deleted 3,600 seconds after creation. No submitted text or audio is sent to OpenRouter or another external TTS provider.

Current planFree200 requests per month

Quota

Free usage

Used0
Remaining200
Limit200
Resets at 2026-09-30 23:59:59.

Authentication

Bearer token

Authorization: Bearer {serviceTokenHere}

For compatibility with simple image tags and legacy clients, ?token=... and the X-API-Token header are also accepted.

POST

Generate multilingual speech

https://ai.mihajlo.mk/api/text-to-speech-api/v1/generate-speech

Generate an MP3 locally using the selected language and optional voice ID.

ParameterTypeRequiredDescription
textstringYesUTF-8 text to synthesize, up to 5,000 characters.
languagestringNoBCP 47 code returned by GET /voices. Defaults to en-US.
voicestringNoOptional voice ID returned by GET /voices. Leave empty to use the language default.

cURL example

curl --request POST \
  --header "Authorization: Bearer {serviceTokenHere}" \
  --header "Content-Type: application/json" \
  --data '{"text":"Dobro došli u lokalni servis za govor.","language":"hr-HR","voice":"rhvoice:karmela"}' \
  "https://ai.mihajlo.mk/api/text-to-speech-api/v1/generate-speech"

Example response

{
    "success": true,
    "audio_url": "https://ai.mihajlo.mk/storage/tts/7f84c27c8d9249c9a7d5f43d.mp3",
    "format": "mp3",
    "engine": "rhvoice",
    "language": "hr-HR",
    "voice": "Karmela",
    "voice_id": "rhvoice:karmela",
    "expires_in": 3600,
    "expires_at": "2026-08-12T12:00:00Z"
}

Live tester

Login to run live requests. All endpoint documentation remains public.

Login to test
GET

List installed languages and voices

https://ai.mihajlo.mk/api/text-to-speech-api/v1/voices

Return the live local catalog grouped by language, including voice IDs, engines, quality types, and the default voice for each language.

cURL example

curl --request GET \
  --header "Authorization: Bearer {serviceTokenHere}" \
  "https://ai.mihajlo.mk/api/text-to-speech-api/v1/voices"

Example response

{
    "success": true,
    "default_language": "en-US",
    "language_count": 138,
    "voice_count": 166,
    "languages": [
        {
            "code": "en-US",
            "name": "English (United States)",
            "default_voice": "piper:en-us-lessac-medium",
            "voices": [
                {
                    "id": "piper:en-us-lessac-medium",
                    "voice": "en_US-lessac-medium",
                    "language": "en-US",
                    "engine": "piper",
                    "quality": "neural"
                }
            ]
        }
    ]
}

Errors

Standard error envelope

{
  "ok": false,
  "error": "invalid_request",
  "message": "Human-readable explanation"
}

Common statuses: 401 invalid token, 422 invalid parameters, 429 quota used, and 502 upstream or capture failure.