Skip to main content

🗣️ Thai Text-to-Speech (TTS)

🗣️ ระบบแปลงข้อความภาษาไทยเป็นเสียงพูด

Version Status New

Welcome to Thai Text-to-Speech API, an AI product developed by iApp Technology Co., Ltd. Our API converts Thai and English text into natural-sounding speech with high accuracy and speed. The service supports mixed Thai-English sentences and offers multiple voice options.

iApp Text to Speech API

Try Demo

Demo key is limited to 10 requests per day per IP
Click here to get your API key

Getting Started

  1. Prerequisites

    • An API key from iApp Technology
    • Text input in Thai and/or English
    • Maximum text length: No specific limit
    • Supported output format: MP3, WAV
  2. Quick Start

    • Fast processing (less than 1 second)
    • Natural speech generation
    • Support for Thai-English mixed text
  3. Key Features

    • Natural speech synthesis
    • Mixed language support (Thai-English)
    • Emoji support
    • Number, date, and currency value conversion
    • Multiple voice options
    • Fast processing time
  4. Security & Compliance

    • GDPR and PDPA compliant
    • No data retention after processing
How to get API Key?

Please visit API Portal to view your existing API key or request a new one.

Code Examples

Sample Request:

  • เสียงเด็กผู้ชายน้องไข่ต้ม
curl --location --request GET 'https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ'
--header 'apikey: {YOUR_API_KEY}'
  • เสียง คุณซี ฉัตรปวีณ์ ตรีชัชวาลวงศ์ (@ceemeagain)
curl --location --request GET 'https://api.iapp.co.th/thai-tts-cee/tts?text=สวัสดีค่ะเสียงซีสังเคราะห์มาแล้วค่ะ'
--header 'apikey: {YOUR_API_KEY}'
  • เสียงเด็กผู้ชายน้องไข่ต้ม v2
# Thai Only
curl -X POST "https://api.iapp.co.th/thai-tts-kaitom2/tts" \
--header "apikey: YOUR_API_KEY" \
-F "text=สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ พร้อมยินดีให้บริการครับ" \
-F "language=TH" \
--output thai_only.wav

# Thai Mixed with English
curl -X POST "https://api.iapp.co.th/thai-tts-kaitom2/tts" \
--header "apikey: YOUR_API_KEY" \
-F "text=Hello and Welcome. สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ. พร้อมยินดีให้บริการครับ" \
-F "language=TH_MIX_EN" \
--output thai_with_english.wav

Sample Response:

Audio file output (MP3 format). The output audio file can be previewed as below:

  • เสียงเด็กผู้ชายน้องไข่ต้ม
  • เสียง คุณซี ฉัตรปวีณ์ ตรีชัชวาลวงศ์ (@ceemeagain)
  • เสียงเด็กผู้ชายน้องไข่ต้ม v2 (Thai Only)
  • เสียงเด็กผู้ชายน้องไข่ต้ม v2 (Thai Mixed with English)
note

Replace the text parameter in the URL with your desired text to preview different audio outputs. You'll need to add your API key as a header to make it work.

Features & Capabilities

Core Features

  • Natural speech generation
  • Mixed Thai-English text support
  • Emoji conversion
  • Number and date formatting
  • Multiple voice options
  • Fast processing

Supported Fields

  • Thai text
  • English text
  • Emojis
  • Numbers
  • Dates
  • Currency values

API Reference

Text-to-Speech Endpoint (Kaitom Voice)

  • Endpoint: GET https://api.iapp.co.th/thai-tts-kaitom/tts
  • Required Parameters:
    • apikey: Your API key (header)
    • text: Text to convert to speech (query)

Text-to-Speech Endpoint (Cee Voice)

  • Endpoint: GET https://api.iapp.co.th/thai-tts-cee/tts
  • Required Parameters:
    • apikey: Your API key (header)
    • text: Text to convert to speech (query)

Text-to-Speech Endpoint (Kaitom v2 Voice)

  • Endpoint: POST https://api.iapp.co.th/thai-tts-kaitom2/tts
  • Required Parameters:
    • apikey: Your API key (header)
    • text: Text to convert to speech (form data)
  • Optional Parameters:
    • language: Language mode (form data)
    • TH: Thai only
    • TH_MIX_EN: Thai mixed with English (default)

Code Examples

Python

Kaitom v1

import requests

url = "https://api.iapp.co.th/thai-tts-kaitom/tts"
headers = {"apikey": "YOUR_API_KEY"}
params = {"text": "สวัสดีครับ"}

response = requests.get(url, headers=headers, params=params)
with open("output.mp3", "wb") as f:
f.write(response.content)

Kaitom v2

import requests

url = "https://api.iapp.co.th/thai-tts-kaitom2/tts"
headers = {"apikey": "YOUR_API_KEY"}
files = {
"text": (None, "สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ"),
"language": (None, "TH")
}

response = requests.post(url, headers=headers, files=files)
with open("output.wav", "wb") as f:
f.write(response.content)

JavaScript

Kaitom v1

const axios = require("axios")
const fs = require("fs")

let config = {
method: "get",
url: "https://api.iapp.co.th/thai-tts-kaitom/tts",
params: { text: "สวัสดีครับ" },
headers: { apikey: "YOUR_API_KEY" },
responseType: "arraybuffer",
}

axios(config)
.then((response) => {
fs.writeFileSync("output.mp3", response.data)
})
.catch((error) => console.log(error))

Kaitom v2

const axios = require("axios")
const fs = require("fs")
const FormData = require("form-data")

let formData = new FormData()
formData.append("text", "สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ")
formData.append("language", "TH")

let config = {
method: "post",
url: "https://api.iapp.co.th/thai-tts-kaitom2/tts",
headers: {
apikey: "YOUR_API_KEY",
...formData.getHeaders(),
},
data: formData,
responseType: "arraybuffer",
}

axios(config)
.then((response) => {
fs.writeFileSync("output.wav", response.data)
})
.catch((error) => console.log(error))

PHP

Kaitom v1

<?php
$url = "https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ";
$headers = array('apikey: YOUR_API_KEY');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
file_put_contents("output.mp3", $response);
curl_close($ch);
?>

Kaitom v2

<?php
$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.iapp.co.th/thai-tts-kaitom2/tts',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'text' => 'สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ',
'language' => 'TH'
),
CURLOPT_HTTPHEADER => array(
'apikey: YOUR_API_KEY'
),
));

$response = curl_exec($curl);
curl_close($curl);

file_put_contents("output.wav", $response);
?>

Swift

Kaitom v1

import Foundation

let url = URL(string: "https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ&apikey={YOUR_API_KEY}")!
var request = URLRequest(url: url, timeoutInterval: Double.infinity)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("Error:", String(describing: error))
return
}

// Save the data to an MP3 file
let fileManager = FileManager.default
let outputPath = fileManager.temporaryDirectory.appendingPathComponent("output.mp3")

do {
try data.write(to: outputPath)
print("Audio file saved to:", outputPath.path)
} catch {
print("Failed to save file:", error)
}
}

task.resume()

Kaitom v2

let parameters = [
[
"key": "language",
"value": "TH",
"type": "text"
],
[
"key": "text",
"value": "สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ",
"type": "text"
]] as [[String: Any]]

let boundary = "Boundary-\(UUID().uuidString)"
var body = Data()
var error: Error? = nil
for param in parameters {
if param["disabled"] != nil { continue }
let paramName = param["key"]!
body += Data("--\(boundary)\r\n".utf8)
body += Data("Content-Disposition:form-data; name=\"\(paramName)\"".utf8)
if param["contentType"] != nil {
body += Data("\r\nContent-Type: \(param["contentType"] as! String)".utf8)
}
let paramType = param["type"] as! String
if paramType == "text" {
let paramValue = param["value"] as! String
body += Data("\r\n\r\n\(paramValue)\r\n".utf8)
} else {
let paramSrc = param["src"] as! String
let fileURL = URL(fileURLWithPath: paramSrc)
if let fileContent = try? Data(contentsOf: fileURL) {
body += Data("; filename=\"\(paramSrc)\"\r\n".utf8)
body += Data("Content-Type: \"content-type header\"\r\n".utf8)
body += Data("\r\n".utf8)
body += fileContent
body += Data("\r\n".utf8)
}
}
}
body += Data("--\(boundary)--\r\n".utf8);
let postData = body


var request = URLRequest(url: URL(string: "https://api.iapp.co.th/thai-tts-kaitom2/tts")!,timeoutInterval: Double.infinity)
request.addValue("YOUR_API_KEY", forHTTPHeaderField: "apikey")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}

task.resume()

Kotlin

Kaitom v1

import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File
import java.io.FileOutputStream

fun main() {
val client = OkHttpClient()

val request = Request.Builder()
.url("https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ&apikey={YOUR_API_KEY}")
.build()

val response = client.newCall(request).execute()

if (response.isSuccessful) {
// Get response body as bytes
val responseBody = response.body?.bytes()

if (responseBody != null) {
// Save to a file
val outputFile = File("output.mp3")
FileOutputStream(outputFile).use { fos ->
fos.write(responseBody)
println("Audio file saved to: ${outputFile.absolutePath}")
}
} else {
println("Response body is empty.")
}
} else {
println("Request failed with status code: ${response.code}")
}
}

Kaitom v2

val client = OkHttpClient()
val mediaType = "text/plain".toMediaType()
val body = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("language","TH")
.addFormDataPart("text","สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ")
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/thai-tts-kaitom2/tts")
.post(body)
.addHeader("apikey", "YOUR_API_KEY")
.build()
val response = client.newCall(request).execute()

Java

Kaitom v1

import okhttp3.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
public static void main(String[] args) throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
.url("https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ&apikey={YOUR_API_KEY}")
.method("GET", body)
.build();
Response response = client.newCall(request).execute();

if (response.isSuccessful()) {
// Get the response body as bytes
byte[] responseBody = response.body().bytes();

// Save the response to a file
File outputFile = new File("output.mp3");
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
fos.write(responseBody);
System.out.println("Audio file saved to: " + outputFile.getAbsolutePath());
} catch (IOException e) {
System.err.println("Failed to save the file: " + e.getMessage());
}
} else {
System.err.println("Request failed with status code: " + response.code());
}

// Close the response
response.close();
}
}

Kaitom v2

OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("language","TH")
.addFormDataPart("text","สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ")
.build();
Request request = new Request.Builder()
.url("https://api.iapp.co.th/thai-tts-kaitom2/tts")
.method("POST", body)
.addHeader("apikey", "YOUR_API_KEY")
.build();
Response response = client.newCall(request).execute();

Dart

Kaitom v1

import 'dart:io';
import 'package:http/http.dart' as http;

void main() async {
// Create the GET request
var request = http.Request(
'GET',
Uri.parse(
'https://api.iapp.co.th/thai-tts-kaitom/tts?text=สวัสดีครับ&apikey={YOUR_API_KEY}'),
);

// Send the request
http.StreamedResponse response = await request.send();

if (response.statusCode == 200) {
// Save the response to a file
final file = File('output.mp3');
final bytes = await response.stream.toBytes();
await file.writeAsBytes(bytes);

print('Audio file saved to: ${file.path}');
} else {
print('Request failed: ${response.reasonPhrase}');
}
}

Kaitom v2

var headers = {
'apikey': 'YOUR_API_KEY'
};
var data = FormData.fromMap({
'language': 'TH',
'text': 'สวัสดีครับ น้องไข่ต้ม มาแล้วฮะ'
});

var dio = Dio();
var response = await dio.request(
'https://api.iapp.co.th/thai-tts-kaitom2/tts',
options: Options(
method: 'POST',
headers: headers,
),
data: data,
);

if (response.statusCode == 200) {
print(json.encode(response.data));
}
else {
print(response.statusMessage);
}

Limitations and Best Practices

Limitations

  • Thai and English language support only
  • Two voice options available:
    • Kaitom (male voice)
    • Cee (female celebrity voice)
    • Only one voice option available (Kaitom v2)
    • Only speaker_id 0 is supported

Best Practices

  • Use proper punctuation
  • Keep sentences natural and conversational
  • Test with small text segments first
  • Consider context for natural speech flow

Accuracy & Performance

Overall Accuracy

  • Natural speech quality
  • Accurate pronunciation for both Thai and English
  • Proper handling of numbers and special characters

Processing Speed

  • Less than 1 second per request
  • Consistent performance regardless of text length

Factors Affecting Quality

  • Text formatting
  • Punctuation
  • Language mixing
  • Special character usage

History

Version 3.0 (March 2025)

  • Release Kaitom v2 voice
  • Improved speech naturalness
  • Thai-English mixed language support

Version 2.1 (October 2020)

  • Added Kaitom male voice option
  • Improved speech naturalness

Version 2.0 (September 2020)

  • Implemented Deep Learning-based synthesis
  • Added Thai-English mixed language support
  • Improved overall speech quality

Version 1.0 (February 2020)

  • Initial release with HMM-based synthesis
  • Thai language only support

Pricing

AI API Service NameEndpointIC Per CharactersOn-Premise
Thai Text To Speech (TTS)iapp_text_to_speech_v1_cee1 IC/400 CharactersContact
iapp_text_to_speech_v1_kaitom1 IC/400 Characters