Hướng dẫn
Bắt đầu nhanh
Từ khóa API tới file MP3 đầu tiên trong 5 phút.
API của Voice1 là REST + JSON. Mọi tác vụ tạo giọng chạy bất đồng bộ: bạn gửi yêu cầu, nhận về id ngay, rồi hỏi trạng thái tới khi xong và tải file về. Base URL: https://voice1.pro/api.
Chi phí thử nghiệm
Khóa thử vs_test_… (sandbox) chạy được toàn bộ ví dụ dưới đây miễn phí: tác vụ giả lập, không trừ credit — xem mục Sandbox. Khóa thật vs_live_…: 1 credit = 1 ký tự, tối thiểu 500 credit mỗi tác vụ — mỗi lần chạy ví dụ 500 credit.
0. Thử ngay, không cần code
- Tạo Khóa thử ở thẻ "Khóa API của bạn" đầu trang (miễn phí).
- Mở mục Tạo giọng từ văn bản → khung Gửi thử ở cuối trang.
- Dán khóa, bấm Gửi POST → nhận
idtác vụ. - Mở Chi tiết tác vụ / Tải file kết quả:
idđã điền sẵn, bấm Gửi để xem kết quả và nghe file.
1. Tạo khóa API
Đăng nhập, bấm Tạo khóa ở thẻ "Khóa API của bạn" đầu trang, chọn Khóa thử (miễn phí) hoặc Khóa thật, rồi sao chép khóa. Khóa chỉ hiện một lần — hãy cất vào biến môi trường hoặc trình quản lý bí mật.
2. Chọn giọng
voiceId là bắt buộc và không có giá trị mặc định. Lấy từ thư viện giọng (endpoint công khai) và dùng nguyên văn id của giọng.
3. Tạo tác vụ, chờ xong và tải file
// Node.js 18+ — chạy: VOICE1_API_KEY=vs_test_... node quickstart.mjs (Windows: xem mục "Chạy trên Windows")
import { writeFile } from 'node:fs/promises'
const BASE = 'https://voice1.pro'
const headers = {
Authorization: `Bearer ${process.env.VOICE1_API_KEY}`,
'Content-Type': 'application/json',
}
async function api(path, init = {}) {
const res = await fetch(BASE + path, { ...init, headers: { ...headers, ...init.headers } })
if (!res.ok) {
const err = await res.json().catch(() => ({}))
throw new Error(`${res.status} ${err.code}: ${err.message}`)
}
return res
}
// 1. Chọn giọng tiếng Việt
const voices = await (await api('/api/v1/voices?provider=elevenlabs&language=vi&pageSize=5')).json()
const voiceId = voices.items[0]?.id ?? 'jdlxsPOZOHdGEfcItXVu'
// 2. Tạo tác vụ (Idempotency-Key: gửi lại khi mạng lỗi không bị trừ tiền hai lần)
const task = await (await api('/api/v1/text-to-speech/elevenlabs', {
method: 'POST',
headers: { 'Idempotency-Key': `demo-${Date.now()}` },
body: JSON.stringify({
text: 'Xin chào! Đây là giọng nói tạo bằng API Voice1.',
voiceId,
modelId: 'eleven_v4',
}),
})).json()
console.log('Đã tạo', task.id, '— chi phí', task.creditsCost, 'credit (khóa thử: không trừ)')
// 3. Chờ xong — giãn nhịp hỏi theo thời gian ước tính server trả về
let st
for (;;) {
const { items } = await (await api('/api/v1/history/status', {
method: 'POST',
body: JSON.stringify({ ids: [task.id] }),
})).json()
st = items[0]
// Không còn trong danh sách = tác vụ đã bị xóa (bị hủy, credit đã hoàn)
if (!st) throw new Error(`Tác vụ ${task.id} không còn — có thể đã bị xóa`)
if (st.status === 'completed' || st.status === 'failed') break
const waitSec = Math.min(15, Math.max(2, st.etaDoneMinSec ?? 3))
await new Promise((r) => setTimeout(r, waitSec * 1000))
}
if (st.status !== 'completed') throw new Error(`Tác vụ thất bại — xem lý do ở GET /api/v1/history/${task.id}`)
// 4. Tải file (audioUrl là đường dẫn, ghép với BASE; api() đã báo lỗi nếu không phải 2xx)
// Đuôi file lấy theo audioUrl: thường là .mp3, cũng có thể là .wav
const audio = await api(st.audioUrl)
const file = `voice1.${st.audioUrl.split('.').pop()}`
await writeFile(file, Buffer.from(await audio.arrayBuffer()))
console.log('Đã lưu', file)Ghép đường dẫn file
Base URL https://voice1.pro/api + đường dẫn trong tài liệu (/v1/…). Riêng audioUrl (/api/v1/audio/<id>/audio.mp3 hoặc audio.wav) đã có sẵn /api — ghép với https://voice1.pro (không phải với https://voice1.pro/api, nếu không sẽ thành /api/api/…). Tải file qua audioUrl cần header Authorization; downloadUrl là link đầy đủ, không cần khóa. Luôn kiểm tra mã HTTP trước khi ghi file: khi lỗi, body là JSON chứ không phải audio.
Chạy trên Windows
- PowerShell:
$env:VOICE1_API_KEY="vs_test_..."rồipython quickstart.pyhoặcnode quickstart.mjs. - cmd:
set VOICE1_API_KEY=vs_test_...rồi chạy như trên. - cURL trong PowerShell: gõ
curl.exe(chữcurltrong PowerShell là lệnh khác). Hoặc dùng Git Bash / WSL. - Tiếng Việt qua cURL: lưu body vào file UTF-8 rồi gửi
--data-binary @body.json. Gửi thẳng-d '…'có thể hỏng dấu — API trả400kèm hướng dẫn. - Thử nhanh: có thể dán khóa thẳng vào code, nhưng đừng commit hay chia sẻ file đó.
Tiếp theo
- Đọc Luồng bất đồng bộ để theo dõi nhiều tác vụ hiệu quả.
- Đọc Lỗi & xử lý trước khi đưa lên production.
- Không muốn hỏi trạng thái liên tục? Đặt Webhook để được báo khi tác vụ xong.
- Không viết code, dùng Make / n8n / Zapier? Xem Dùng với Make, n8n, Zapier.
- Dùng Postman / Insomnia hay sinh SDK? Tải file OpenAPI hoặc Postman ở đầu trang.
- Cần đọc nhiều file một lúc? Dùng endpoint tạo hàng loạt (tối đa 25 file mỗi lần).