Thai livestream donation alerts
Read donation messages aloud on Thai streams: a voice per tier, code-switched messages handled in one voice, and a typed refusal for the ones with nothing to say.
Ideas to try
Every card plays a real clip generated from its exact script with Nom Yen. Open one in the playground to make it say anything.
How an alert learns to speak
A viewer pays so a streamer hears their name. That is the whole product, and the part that has to work is the moment the message is read out loud, live, in front of an audience. Thailand streams on Facebook above all, where 49.1 million people aged 13 and over are reachable, and Thai tipping services like Tipme already move the money. Reading the message is where it goes wrong: the voice mispronounces a name, or reads an emoji as a word, or arrives so late it lands on the wrong moment of the stream. This page is written for the platform rather than the streamer, because one integration carries every channel on it, and because the platform is the one who gets blamed when a message reads badly.
Sources:DataReportal (2026)(opens in a new tab)Tipme(opens in a new tab)
- Map the tier to a voiceA donation tier is a voice id in your configuration. Higher tiers get a voice viewers recognise, and the catalog's 26 voices are enough that a platform can offer the choice to streamers.
- Send the message you already moderatedThe text arrives as your platform approved it. Speech takes it as given: there is no profanity filter on this side, and moderation belongs where you already do it.
- Play it, or skip itA 200 returns audio for the overlay. A message with nothing speakable in it answers 422 and refunds, which is the signal to skip the alert rather than play two seconds of nothing.
One night on a channel
Donation traffic is spiky by nature. Per-character billing is what keeps a good night from being an operational surprise.
What reading donations costs
| Workload | Characters | Credits | Cost |
|---|---|---|---|
| One stream, 40 donations | 3,600 | 54 | $0.05 |
| One channel, 20 streams a month | 72,000 | 1,080 | $1.08 |
| 1,000 active channels for a month | about $1,080 | ||
Computed at 15 credits per 1,000 characters over a 90-character message. A channel that streams less is billed less, and one that does not stream is not billed.
The alert, from donation to audio
donation received
amount 100 THB, tier: supporter
message: ขอบคุณครับ สู้ ๆ นะ 🎉🎉🎉
your platform
moderation, name lookup, tier -> voice id
POST /v1/tts
{ "voice": "mooping", "text": "..." }
200 audio/mpeg -> overlay
a message of only 🎉🎉🎉
422 unspeakable_text -> refunded, alert skippedThe emoji-only donation is the event every integration meets and few handle. It answers with a typed refusal and a refund, so the overlay skips the alert instead of playing silence.
For developers
The TypeScript and Python quickstarts post one message and take back the audio an overlay plays. The options request shows the voice, model, and format fields a tier pins once.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.paxalabs.com/v1/tts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
voice: "khanomkrok",
model: "paxa-tts-flash-v1",
}),
});
if (!response.ok) throw new Error(`TTS failed: ${response.status}`);
await writeFile("speech.mp3", Buffer.from(await response.arrayBuffer()));import os
import requests
response = requests.post(
"https://api.paxalabs.com/v1/tts",
headers={"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"},
json={"text": "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs", "voice": "khanomkrok", "model": "paxa-tts-flash-v1"},
)
response.raise_for_status()
with open("speech.mp3", "wb") as f:
f.write(response.content)curl -X POST https://api.paxalabs.com/v1/tts \
-H "Authorization: Bearer $PAXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
"voice": "khanomkrok",
"model": "paxa-tts-flash-v1",
"format": "mp3",
"stream": false
}' \
--output speech.mp3Hear the voices
Moo PingMale0:03
Confident young voice with street energy for ads and shorts.
บอกเลยครับ คลิปนี้ห้ามพลาด กดติดตามไว้ก่อนเลย เดี๋ยวหาว่าไม่เตือน
Khanom KrokMale0:03
Calm, unhurried elder voice and the roster's male lead: documentary, heritage storytelling, and narration.
สมัยผมยังหนุ่ม แถวนี้ยังเป็นทุ่งนา เดินไปตลาดทีหนึ่งก็ค่อนวันแล้วครับ
Nom YenFemale0:06
Bright, energetic voice and the roster's female lead: promos, social clips, and everyday product speech.
ยินดีต้อนรับสู่ Paxa Labs ค่ะ เสียงภาษาไทยที่สลับเป็น English ได้กลางประโยค อย่างเป็นธรรมชาติ
TakoFemale0:05
Friendly young narrator for audiobooks, recaps, and explainers.
ยามเช้าในกรุงเทพฯ แสงแดดอ่อน ๆ ทาบลงบนถนนที่เริ่มคึกคัก
A few of the 26 production voices, generated from the API with the published voice ids. The full roster plays on the Text-to-Speech page.
Why donation messages are hard to read
A donation message is short, unpunctuated, and written the way people chat: Thai grammar with English words dropped inside it, a personal name that may be spelled unusually, and an amount to read as a number rather than as digits. Paxa TTS Flash reads tone from spelling and carries both languages in one voice, which is what a message like this needs in the second it has.
Common questions
- What happens to a donation that is only emoji?
- It answers 422 unspeakable_text and the charge is refunded. Treat it as the signal to skip the alert; retrying the same message fails the same way.
- Can each donation tier have its own voice?
- Yes. A voice is a fixed id, and a tier is a mapping to one. You can offer streamers any of the 26 in the catalog, including the regional accents.
- Do you filter what the message says?
- No. Speech reads the text it is given, and it only refuses text with nothing speakable in it. Moderation stays on your platform, where the rest of your rules already live.
- How does a message that mixes Thai and English read?
- In one voice, without a hand-off. Thai gaming chat switches languages constantly, and an English word inside a Thai sentence stays in the same speaker's delivery.
- What does a busy channel cost?
- About $1.08 a month for a channel reading 40 donations across 20 streams. Billing follows the characters read, so a quiet month bills less.
Start with free credits
Sign in with Google, GitHub, or Hugging Face and spend 100 one-time free credits on your own text.