🗣️ Thai Text-to-Speech (TTS)
🗣️ ระบบแปลงข้อความภาษาไทยเป็นเสียงพูด
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.

Try Demo
Getting Started
-
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
-
Quick Start
- Fast processing (less than 1 second)
- Natural speech generation
- Support for Thai-English mixed text
-
Key Features
- Natural speech synthesis
- Mixed language support (Thai-English)
- Emoji support
- Number, date, and currency value conversion
- Multiple voice options
- Fast processing time
-
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 onlyTH_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 Name | Endpoint | IC Per Characters | On-Premise |
---|---|---|---|
Thai Text To Speech (TTS) | iapp_text_to_speech_v1_cee | 1 IC/400 Characters | Contact |
iapp_text_to_speech_v1_kaitom | 1 IC/400 Characters |