KHUYẾN MÃISự trở lại World Cup – Tặng thêm 20% credits cho tất cả gói Pro đến hết 31/07/2026
Nâng cấp

🔒 Dữ liệu bản miễn phí có thể được dùng để cải thiện AI. Nâng cấp Pro để bảo mật tuyệt đối

Tài liệu lập trình viên TTS Forge

REST API • Single TTS • Multi Voice • SRT to Speech

Hướng dẫn sử dụng

🎧 Demo & Ví dụ API Trực Tiếp

Khám phá TTS For Free API — thử demo trực tiếp hoặc xem các ví dụ mã sẵn có bằng nhiều ngôn ngữ.

Tổng quan

TTSForFree cung cấp pipeline TTS bất đồng bộ. Bạn tạo job bằng REST API, sau đó lấy file hoàn tất qua polling hoặc callback tùy flow.

  • 70+ ngôn ngữ và 1.800+ giọng nói
  • Có single TTS, multi voice kiểu podcast và SRT-to-speech
  • Có API lịch sử cho job đơn, lịch sử theo voice và lịch sử job merge
  • Không fetch audio trước khi job là SUCCESS

API này hiện hỗ trợ gì

Đây là các nhóm API public cho user hiện có trong backend mà frontend có thể bám theo.

Single TTS

Chuyển một đoạn text thành một file audio qua `CreateBy`, sau đó kiểm tra bằng `Status` hoặc nhận callback qua `CallbackUrl`.

Multi Voice

Tạo audio nhiều người nói hoặc kiểu podcast qua `CreateMulti` với một `ConnectionId` và nhiều block.

SRT to Speech

Tạo audio lồng tiếng từ các block subtitle có `StartMs` và `EndMs` qua `CreateSrt`.

Realtime Updates

Một số flow async có tiến trình xử lý nền và trả kết quả sau, còn phần docs public bên dưới tập trung vào contract request và response.

History APIs

Lấy lịch sử job đơn, lịch sử theo voice hoặc lịch sử job merge của chính user đã đăng nhập.

Tài liệu OpenAPI

Xem schema public mới nhất trong Swagger.

Xác thực

Gửi `X-API-Key` trong header của mọi request public.

Muốn lấy API key thì vào `/`. Ở khu vực voice có nút copy để copy đúng giá trị `Voice` trước khi gọi API. Riêng các API lịch sử cần thêm `Authorization: Bearer YOUR_JWT` vì chúng trả về lịch sử của chính user hiện tại.

Header cần gửi
X-API-Key: YOUR_API_KEY
Authorization: Bearer YOUR_JWT // chỉ cần cho các API lịch sử

Ngôn ngữ & Giọng đọc

Hãy gọi các API này trước khi generate để frontend có dữ liệu ngôn ngữ, voice và giới hạn độ dài hiện tại.

`Pitch` phụ thuộc provider. Không phải voice nào cũng hỗ trợ.

Get List Language
curl -X GET "https://api.ttsforfree.com/api/Common/GetListLanguage" \
  -H "X-API-Key: YOUR_API_KEY"
Get List Voice
curl -X GET "https://api.ttsforfree.com/api/Common/GetListVoice?lang=vi&type=multivoice" \
  -H "X-API-Key: YOUR_API_KEY"
Get Config Max Length
curl -X GET "https://api.ttsforfree.com/api/Common/GetConfigMaxLength" \
  -H "X-API-Key: YOUR_API_KEY"

Tạo Single TTS

Dùng `CreateBy` cho một đoạn text và một voice. `Pitch` là optional. `CallbackUrl` cũng là optional.

Public DTO của `CreateBy` không yêu cầu `ConnectionId`.

cURL Request
curl --location "https://api.ttsforfree.com/api/TTS/CreateBy" \
  --header "X-API-Key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "Texts": "Xin chào mọi người",
    "Voice": "v1:TldK3n9ei9wctuSlNYhG_cJ4UULVT8ZGjhxcuoaFow2hDTDsuTCuvaOYrVY",
    "Pitch": 0,
    "CallbackUrl": "https://your-app.com/api/tts/callback"
  }'
JSON Body
{
  "Texts": "Xin chào mọi người",
  "Voice": "v1:TldK3n9ei9wctuSlNYhG_cJ4UULVT8ZGjhxcuoaFow2hDTDsuTCuvaOYrVY",
  "Pitch": 0,
  "CallbackUrl": "https://your-app.com/api/tts/callback"
}
Create Response
{
  "Id": 12345,
  "Message": "Proccessing",
  "Status": "PENDING",
  "Data": "",
  "ExpectUrl": "https://cdn.ttsforfree.com/20250606/abc.mp3",
  "ShareKey": "sha256..."
}

Kiểm tra trạng thái Single Job

Dùng `Id` trả về làm job id cho job đơn. Nếu không dùng `CallbackUrl` thì poll endpoint này.

Nếu request trúng cache thì `Data` có thể có URL ngay. Nếu chưa xong thì chờ `Status` chuyển sang `SUCCESS`.

Status Request
curl -X GET "https://api.ttsforfree.com/api/TTS/Status/12345" \
  -H "X-API-Key: YOUR_API_KEY"
Status Response
{
  "Id": 12345,
  "Status": "SUCCESS",
  "Data": "https://cdn.ttsforfree.com/20250606/abc.mp3"
}

Tạo Multi Voice

Dùng `CreateMulti` cho nội dung nhiều người nói hoặc podcast. `ConnectionId` là bắt buộc.

cURL Request
curl --location "https://api.ttsforfree.com/api/TTS/CreateMulti" \
  --header "X-API-Key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "ConnectionId": "signalr-connection-id",
    "Blocks": [
      {
        "Texts": "Chào mừng đến với chương trình",
        "Voice": "v1:host_voice",
        "Volume": 1,
        "Speed": 1,
        "Pitch": 0,
        "PauseAfterMs": 300
      },
      {
        "Texts": "Cảm ơn vì đã mời tôi",
        "Voice": "v1:guest_voice",
        "Volume": 1,
        "Speed": 1,
        "Pitch": 0,
        "PauseAfterMs": 500
      }
    ]
  }'
JSON Body
{
  "ConnectionId": "signalr-connection-id",
  "Blocks": [
    {
      "Texts": "Chào mừng đến với chương trình",
      "Voice": "v1:host_voice",
      "Volume": 1,
      "Speed": 1,
      "Pitch": 0,
      "PauseAfterMs": 300
    },
    {
      "Texts": "Cảm ơn vì đã mời tôi",
      "Voice": "v1:guest_voice",
      "Volume": 1,
      "Speed": 1,
      "Pitch": 0,
      "PauseAfterMs": 500
    }
  ]
}
Create Response
{
  "Id": 6789,
  "Message": "Success",
  "ExpectUrl": "https://cdn.ttsforfree.com/audio_merge/3f9b5a35-9ac4-4d51-a8fe-2e4d91523a88.mp3"
}

Tạo SRT to Speech

Dùng `CreateSrt` khi mỗi block đã có timeline subtitle. `ConnectionId` là bắt buộc.

Hiện tại Gemini voice chưa được hỗ trợ ở mode SRT.

cURL Request
curl --location "https://api.ttsforfree.com/api/TTS/CreateSrt" \
  --header "X-API-Key: YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "ConnectionId": "signalr-connection-id",
    "Blocks": [
      {
        "Texts": "Xin chào mọi người",
        "Voice": "v1:voice_1",
        "Volume": 1,
        "Speed": 0.9,
        "Pitch": 0,
        "StartMs": 0,
        "EndMs": 1800
      },
      {
        "Texts": "Chào mừng quay trở lại",
        "Voice": "v1:voice_1",
        "Volume": 1,
        "Speed": 0.9,
        "Pitch": 0,
        "StartMs": 2200,
        "EndMs": 4200
      }
    ]
  }'
JSON Body
{
  "ConnectionId": "signalr-connection-id",
  "Blocks": [
    {
      "Texts": "Xin chào mọi người",
      "Voice": "v1:voice_1",
      "Volume": 1,
      "Speed": 0.9,
      "Pitch": 0,
      "StartMs": 0,
      "EndMs": 1800
    },
    {
      "Texts": "Chào mừng quay trở lại",
      "Voice": "v1:voice_1",
      "Volume": 1,
      "Speed": 0.9,
      "Pitch": 0,
      "StartMs": 2200,
      "EndMs": 4200
    }
  ]
}
Create Response
{
  "Id": 6790,
  "Message": "Success",
  "ExpectUrl": "https://cdn.ttsforfree.com/audio_merge/f0d4cb65-7d10-4f53-b930-1b231d2414d9.mp3"
}

Kiểm tra trạng thái Multi hoặc SRT

Dùng merged job `Id` trả về từ `CreateMulti` hoặc `CreateSrt`.

Status Request
curl -X GET "https://api.ttsforfree.com/api/TTS/Multi/Status/6789" \
  -H "X-API-Key: YOUR_API_KEY"
Status Response
{
  "Id": 6789,
  "Status": "SUCCESS",
  "Data": "https://cdn.ttsforfree.com/audio_merge/3f9b5a35-9ac4-4d51-a8fe-2e4d91523a88.mp3"
}

Lấy chi tiết job

Với multi voice và SRT, endpoint này trả về job merge cùng toàn bộ block audio con.

Dùng `FinalAudioUrl` cho file merge cuối và `Blocks[].FilePath` cho file của từng block.

Job Detail Request
curl -X GET "https://api.ttsforfree.com/api/TTS/GetJobTTSDetail?jobId=6789" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_JWT"
Job Detail Response
{
  "Id": 1,
  "Message": "Success",
  "Data": {
    "Id": 6789,
    "TotalBlocks": 2,
    "StatusId": 200,
    "StatusName": "SUCCESS",
    "FinalAudioUrl": "https://cdn.ttsforfree.com/audio_merge/3f9b5a35-9ac4-4d51-a8fe-2e4d91523a88.mp3",
    "Blocks": [
      {
        "Id": 12345,
        "Text": "Chào mừng đến với chương trình",
        "Voice": "v1:host_voice",
        "FilePath": "https://cdn.ttsforfree.com/20250606/block1.mp3",
        "StatusId": 200
      }
    ]
  }
}

API lịch sử

Các API lịch sử gắn với user account. Chúng trả về job của user hiện tại, vì vậy cần `Authorization: Bearer YOUR_JWT`.

Dùng `GetHistory` cho job single TTS, `GetHistoryVoice` cho lịch sử rút gọn theo voice, và `GetHistoryMulti` cho job merge. Nếu muốn lịch sử SRT merge thì gọi `GetHistoryMulti` với `jobType=Srt`.

Get Single Job History
curl -X GET "https://api.ttsforfree.com/api/TTS/GetHistory?page=1&pageSize=10" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_JWT"
Get Voice History
curl -X GET "https://api.ttsforfree.com/api/TTS/GetHistoryVoice?page=1&pageSize=10" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_JWT"
Get Multi History
curl -X GET "https://api.ttsforfree.com/api/TTS/GetHistoryMulti?page=1&pageSize=10&jobType=Tts" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_JWT"
Get SRT History
curl -X GET "https://api.ttsforfree.com/api/TTS/GetHistoryMulti?page=1&pageSize=10&jobType=Srt" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Authorization: Bearer YOUR_JWT"
History Response Example
{
  "Id": 1,
  "Message": "Success",
  "TotalRows": 1,
  "Data": [
    {
      "Id": 6789,
      "TotalBlocks": 2,
      "StatusId": 150,
      "StatusName": "MERGE_REQUESTED",
      "FinalAudioUrl": "",
      "Blocks": [
        {
          "Id": 12345,
          "Text": "Chào mừng đến với chương trình",
          "Voice": "v1:host_voice",
          "FilePath": "https://cdn.ttsforfree.com/20250606/block1.mp3",
          "StatusId": 200
        }
      ]
    }
  ]
}

Callback cho single job

Nếu truyền `CallbackUrl` trong `CreateBy`, server sẽ POST payload hoàn tất về URL của bạn khi single TTS hoàn thành.

Hiện tại callback public áp dụng cho `CreateBy`. Với multi voice và SRT, hãy dùng các endpoint create và status ở phía trên.

Callback Payload
POST https://your-app.com/api/tts/callback
Content-Type: application/json

{
  "Id": 12345,
  "Status": "SUCCESS",
  "Action": "ResponseTTSNotification",
  "FilePath": "https://cdn.ttsforfree.com/20250606/abc.mp3",
  "Data": "https://cdn.ttsforfree.com/20250606/abc.mp3",
  "Hash": "sha256...",
  "CompletedAt": "2026-06-06T10:10:10Z"
}

Giới hạn & Hạn ngạch

  • Nếu muốn validate từ client trước khi submit, hãy gọi `GetConfigMaxLength` trước.
  • Request multi voice và SRT vẫn bị validate theo từng block nên có thể fail dù tổng thể nhìn vẫn hợp lệ.
  • Nếu cần hạn mức cao hơn hoặc dùng thương mại, hãy liên hệ đội ngũ.

Mã lỗi

Common Errors
400 Bad Request    // thiếu text, block sai dữ liệu, hoặc timeline không hợp lệ
401 Unauthorized   // thiếu hoặc sai API key hay user token
403 Forbidden      // hết quota hoặc voice không được phép dùng
404 Not Found      // không tìm thấy job id
429 Too Many       // bị giới hạn tốc độ
500 Server Error   // lỗi tạm thời, nên retry với backoff

Ý nghĩa StatusId

Đây là các giá trị số quan trọng nhất nên giải thích rõ trong docs frontend khi đọc lịch sử merge hoặc job detail.

100

Đang chờ

Job đã được nhận và đang chờ hoặc đang pending trong pipeline xử lý.

150

Đang merge SRT / đã yêu cầu merge

Các block đã xử lý xong phần chính và hệ thống đang yêu cầu hoặc đang thực hiện bước ghép audio cuối.

200

Thành công

Audio cuối cùng đã sẵn sàng. Lúc này mới nên dùng `Data`, `ExpectUrl` hoặc `FinalAudioUrl`.

-100

Lỗi

Job đã fail. Không nên fetch URL audio cuối cùng cho tới khi có một lượt chạy thành công mới.

FAQ

Câu hỏi thường gặp

Q: Nên ưu tiên polling hay cách nào khác?

A: Trong docs public này, nên ưu tiên polling. Dùng `Status` cho single TTS và `Multi/Status` cho multi voice hoặc SRT. Thông thường poll mỗi 5 giây là đủ cho đa số frontend.

Q: Một job video dài thường mất bao lâu?

A: Với nhu cầu thực tế, job `multi voice` và `srt` cho một video dài khoảng 2 đến 3 giờ thường có thể xong khoảng 5 phút mỗi job. Thời gian thực tế vẫn phụ thuộc số block, loại voice và tải hàng đợi.

Q: Có tips nào để chạy ổn hơn không?

A: Nếu làm workflow dài, nên ưu tiên `multi voice` và `srt` vì linh hoạt hơn cho nội dung dài. Hãy chia block rõ ràng, giữ timeline sạch và poll status thay vì fetch output quá sớm.

Q: Rate limit hiện như thế nào?

A: Gói free sẽ có giới hạn thấp hơn theo phút và theo ngày. Gói đã thanh toán sẽ có hạn mức cao hơn. Chính sách cụ thể có thể thay đổi theo package, vì vậy hãy xử lý an toàn khi gặp 429 và liên hệ đội ngũ nếu cần throughput lớn hơn.

Q: Lấy voice key ở đâu?

A: Vào trang chủ `/`. Ở khu vực voice sẽ có nút copy key. Bạn có thể test voice trước ngay tại đó rồi copy đúng giá trị `Voice` để đưa vào request API.

Giấy phép & Điều khoản

Gói miễn phí phù hợp cho test và prototype. Nếu dùng thương mại, phân phối lại hoặc cần quota lớn hơn, hãy liên hệ [email protected].