OnterVOICE AI

ONTER VOICE AI

Tài liệu Onter Voice API v1

Hướng dẫn API giọng nói: xác thực, lấy giọng, tạo audio, theo dõi tác vụ, voice cloning, giới hạn và xử lý lỗi.

Bắt đầu

Đăng nhập, vào Tài khoản và tạo API key. Lưu key ở backend hoặc biến môi trường; không nhúng vào JavaScript công khai. Gửi Authorization: Bearer YOUR_API_KEY khi gọi API.

Danh sách giọng

GET /v1/voices trả về data là danh sách gồm id, name, gender, region và preview_url. Dùng id được trả về làm voice_id; không tự suy đoán danh sách giọng.

Tạo audio và theo dõi tác vụ

POST /v1/tts với text, voice_id và output_format (mp3 hoặc wav) trả HTTP 202 cùng data.job_id. GET /v1/jobs/{id} để theo dõi queued, processing, completed hoặc failed. Khi hoàn tất, tải qua đường dẫn data.audio với cùng API key.

Idempotency và lỗi

Gửi Idempotency-Key ổn định cho cùng một tác vụ khi thử lại do lỗi mạng. Dùng lại key với nội dung khác trả 409. 401: key không hợp lệ; 403: thiếu quyền; 404: dữ liệu không thuộc tài khoản hoặc không còn; 422: đầu vào sai; 429: vượt giới hạn; 503: dịch vụ tạo giọng tạm chưa sẵn sàng.

Hạn mức và sử dụng

GET /v1/usage cung cấp ký tự, thời lượng và số tác vụ trong ngày UTC. Xem giới hạn văn bản hiện hành tại /v1/session. Khi nhận 429, tuân theo Retry-After. Kiểm tra tác vụ mỗi 3–5 giây; không gọi tạo lại liên tục.

API giọng cá nhân

POST /v1/custom-voices nhận multipart file, name, consent=true và policy_version lấy từ /v1/session. Sau khi lưu, POST /v1/clone với text và custom_voice_id. GET /v1/custom-voices chỉ trả giọng của tài khoản; DELETE /v1/custom-voices/{id} để xóa. API key của tài khoản có quyền tương đương với dữ liệu giọng cá nhân của tài khoản đó.

Bảo quản audio

URL tải yêu cầu xác thực cùng chủ sở hữu, không phải đường dẫn chia sẻ công khai. Tải audio trước ngày hết hạn lưu trữ. Hãy lưu bản cần dùng lâu dài trong hệ thống của bạn.

Ví dụ curl

curl https://voiceai.onter.vn/v1/voices

curl https://voiceai.onter.vn/v1/tts \
  -H "Authorization: Bearer $ONTER_VOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: audio-example-001" \
  -d '{"text":"Xin chào, chúc bạn một ngày tốt lành.","voice_id":"Minh Đức","output_format":"mp3"}'

curl https://voiceai.onter.vn/v1/jobs/JOB_ID \
  -H "Authorization: Bearer $ONTER_VOICE_API_KEY"

Ví dụ JavaScript (backend)

const response = await fetch("https://voiceai.onter.vn/v1/tts", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.ONTER_VOICE_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ text: "Xin chào.", voice_id: "Minh Đức" })
});
if (!response.ok) throw new Error("HTTP " + response.status);
const { data } = await response.json();
console.log(data.job_id); // Poll status_url, then download with the same key.

Ví dụ Python

import os, time, requests
base = "https://voiceai.onter.vn"
headers = {"Authorization": "Bearer " + os.environ["ONTER_VOICE_API_KEY"]}
response = requests.post(base + "/v1/tts", headers=headers,
    json={"text": "Xin chào.", "voice_id": "Minh Đức"}, timeout=30)
response.raise_for_status()
job_id = response.json()["data"]["job_id"]
for _ in range(240):
    response = requests.get(base + "/v1/jobs/" + job_id, headers=headers, timeout=30)
    response.raise_for_status()
    job = response.json()["data"]
    if job["status"] == "failed":
        raise RuntimeError(job["error"])
    if job["status"] == "completed":
        audio = requests.get(base + job["audio"]["mp3"], headers=headers, timeout=60)
        audio.raise_for_status()
        open("onter-voice.mp3", "wb").write(audio.content)
        break
    time.sleep(5)
else:
    raise TimeoutError("Check the same job later; do not resubmit blindly.")