Text-to-Speech
Convert article text to spoken audio using the MisarBlog text-to-speech API.
Overview
MisarBlog's text-to-speech (TTS) system converts article content to MP3 audio. The API works on a chunk-based model — the client splits the article into text segments, requests audio for each chunk, and the player assembles them in sequence. Chunks are cached server-side for 24 hours.
The TTS player in the MisarBlog dashboard handles chunking automatically. Use this API directly if you're building a custom reader or audio player for MisarBlog content.
Generate Audio Chunk
/blog/ttsConverts a single text chunk to MP3 audio. Returns cached audio if the chunk has been generated before. No API key authentication is required, but the endpoint is rate-limited by IP (60 requests per minute).
Request body
articleIdstringbodyrequiredUUID of the article this chunk belongs to. Used as part of the cache key.
contentHashstringbodyrequiredShort hex hash of the article's full content (6–16 hex characters). Used as a cache-bust key — when article content changes, a new hash invalidates the old audio.
chunkIndexnumberbodyrequiredZero-based index of this chunk in the article sequence (0–199).
textstringbodyrequiredThe text to synthesize for this chunk. Maximum ~4000 characters per chunk.
Response
A successful 200 OK returns binary MP3 audio data with Content-Type: audio/mpeg.
Content-Typeaudio/mpegAudio format.
Cache-Controlprivate, max-age=8640024-hour browser cache.
X-CacheHIT | MISSWhether audio was served from cache.
{
"articleId": "550e8400-e29b-41d4-a716-446655440000",
"contentHash": "a1b2c3d4",
"chunkIndex": 0,
"text": "Welcome to my first article. This is the opening paragraph of the article content."
}Content-Type: audio/mpeg
Cache-Control: private, max-age=86400
X-Cache: HIT
<binary MP3 audio data>Rate Limits
| Tier | Limit |
|---|---|
| All | 60 requests per 60 seconds per IP |
Example
async function playArticleAudio(articleId: string, chunks: string[], contentHash: string) {
const audioContext = new AudioContext();
for (let i = 0; i < chunks.length; i++) {
const res = await fetch("https://api.misar.io/blog/tts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
articleId,
contentHash,
chunkIndex: i,
text: chunks[i],
}),
});
if (!res.ok) {
console.error(`Chunk ${i} failed:`, res.status);
continue;
}
const arrayBuffer = await res.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
source.start();
// wait for this chunk to finish before playing the next
await new Promise<void>((resolve) => {
source.onended = () => resolve();
});
}
}Chunk size limit
Each text chunk must be under ~4000 characters. Split article content at sentence boundaries to keep chunks within this limit and ensure natural-sounding audio.