Home / Blog / Free text to speech API
Need to turn text into spoken audio without creating yet another developer account? This guide shows you how to use a free text to speech API that needs no signup and no API key — send a POST request with your text, get back an MP3. Tested live, with copy-paste code in cURL, JavaScript, and Python.
Endpoint: POST https://ahm7xmakki.com/api/tts
Body (JSON): {"text": "your text", "voiceIndex": 1}
Returns: MP3 audio (audio/mpeg)
Auth: none. Playground: ahm7xmakki.com/speech
Unlike browser speechSynthesis (which sounds robotic and varies by device), this runs server-side and returns a real audio file you can save, embed, or stream.
curl -X POST https://ahm7xmakki.com/api/tts \
-H "Content-Type: application/json" \
-d '{"text":"Hello world, this is a test.","voiceIndex":1}' \
-o hello.mp3
# Play it (macOS / Linux)
ffplay hello.mp3 # or: mpg123 hello.mp3
That's it. The voiceIndex is 1-based — try 1, 2, 3 to hear different voices.
Fetch the MP3 as a blob and play it directly in the browser — no file download needed:
async function speak(text, voiceIndex = 1) {
const res = await fetch("https://ahm7xmakki.com/api/tts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text, voiceIndex })
});
if (!res.ok) throw new Error("TTS failed: " + res.status);
const audio = new Audio(URL.createObjectURL(await res.blob()));
audio.play();
return audio;
}
// Usage
document.getElementById("readBtn").onclick = () =>
speak("Welcome to my website. This audio was generated by a free API.");
import requests
def text_to_speech(text, voice_index=1, out="out.mp3"):
r = requests.post(
"https://ahm7xmakki.com/api/tts",
json={"text": text, "voiceIndex": voice_index},
timeout=60,
)
r.raise_for_status()
with open(out, "wb") as f:
f.write(r.content)
return out
text_to_speech("Breaking news: free APIs still exist in 2026.")
| Parameter | Type | Required | Notes |
|---|---|---|---|
text | string | Yes | The text to speak. Keep it under a few thousand characters per request. |
voiceIndex | integer | Yes | 1-based voice selector. Try 1–4 for different voices. |
The response has Content-Type: audio/mpeg. If you get JSON instead (like {"error": "..."}), check that you used POST with a JSON body and included voiceIndex — a GET request returns {"error":"Method not allowed"}.
Generate narration for YouTube videos, reels, or ads without recording. Batch-generate one MP3 per paragraph, then stitch them with ffmpeg:
ffmpeg -i part1.mp3 -i part2.mp3 -i part3.mp3 \
-filter_complex "[0:a][1:a][2:a]concat=n=3:v=0:a=1" narration.mp3
Add a "listen to this article" button to your blog. One fetch call, zero dependencies, works on every browser.
Generate pronunciation audio for vocabulary lists. Different voiceIndex values let students hear varied voices.
Telegram/Discord bots can turn long messages into voice notes on demand — handy for hands-free updates.
Understanding the request lifecycle helps you debug faster. Here's what happens when you POST to /api/tts:
text and voiceIndex are validated — missing either one returns a JSON error instead of audio.Content-Type: audio/mpeg.This is why the response type check matters: a 200 with audio/mpeg means success, while a 200 with application/json means the API is telling you something went wrong. Always branch on content type, not just status code:
const res = await fetch("https://ahm7xmakki.com/api/tts", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ text, voiceIndex: 1 })
});
const ct = res.headers.get("content-type") || "";
if (!ct.includes("audio")) {
const err = await res.json();
throw new Error("TTS error: " + (err.error || res.status));
}
// safe to treat body as audio from here
Here's a self-contained HTML page — textarea, voice picker, and a play button. Save it as tts-demo.html and open it in any browser:
<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:40px auto">
<h2>Free TTS Demo</h2>
<textarea id="t" rows="4" style="width:100%">Hello from the free text to speech API.</textarea><br><br>
<label>Voice: <select id="v">
<option value="1">Voice 1</option><option value="2">Voice 2</option>
<option value="3">Voice 3</option><option value="4">Voice 4</option>
</select></label>
<button id="go">Speak</button>
<p id="st"></p>
<script>
document.getElementById("go").onclick = async () => {
const st = document.getElementById("st");
st.textContent = "Generating...";
try {
const res = await fetch("https://ahm7xmakki.com/api/tts", {
method: "POST",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({
text: document.getElementById("t").value,
voiceIndex: +document.getElementById("v").value
})
});
if (!res.headers.get("content-type").includes("audio"))
throw new Error((await res.json()).error || "failed");
new Audio(URL.createObjectURL(await res.blob())).play();
st.textContent = "Playing...";
} catch(e) { st.textContent = "Error: " + e.message; }
};
</script></body></html>
How does a no-signup API compare with the big names? Honestly: paid services (ElevenLabs, OpenAI TTS, Google Cloud TTS) win on voice realism and SSML control. But they all require accounts, keys, and billing. For side projects, prototypes, internal tools, and content where "good enough" narration is fine, the free API wins on speed of integration — you can go from zero to speaking audio in one cURL command, which no key-gated service can match.
Browser-native speechSynthesis is the other free option, but voices differ wildly between devices, quality is inconsistent, and you can't save the output as a file. The API gives you a portable MP3 every time.
What languages are supported? The voices cover major languages; English voices are the most tested. Try your text and listen — that's faster than any docs table.
Is there a character limit? Keep requests to a few thousand characters. For articles, split by paragraph and concatenate the MP3s with ffmpeg.
Can I use the audio commercially? For personal and prototype use, yes. For commercial products with significant traffic, check the terms or contact us.
Why did I get a JSON error instead of audio? The three common causes: you used GET instead of POST, you forgot Content-Type: application/json, or voiceIndex is missing. Fix those and retry.
No code needed to start — open the playground, type something, and hit generate:
When you're ready for more, the full API docs cover every endpoint, and the free APIs roundup lists 9 more no-signup APIs.