Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

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

POST/blog/tts

Converts 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

articleIdstringbodyrequired

UUID of the article this chunk belongs to. Used as part of the cache key.

contentHashstringbodyrequired

Short 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.

chunkIndexnumberbodyrequired

Zero-based index of this chunk in the article sequence (0–199).

textstringbodyrequired

The 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/mpeg

Audio format.

Cache-Controlprivate, max-age=86400

24-hour browser cache.

X-CacheHIT | MISS

Whether 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

TierLimit
All60 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.