Audinote API / v1

ถอดเสียงและสร้างเสียงในแอปของคุณ

ใช้ชื่อโมเดลและเสียงของ Audinote ผ่าน API แบบ JSON สร้างคีย์ส่วนตัว เรียก HTTP หรือสตรีมเสียงและข้อความผ่าน WebSocket

เริ่มใช้งาน

สร้างคีย์ เก็บไว้ที่เซิร์ฟเวอร์ของคุณ แล้วส่งคำขอ JSON ตัวอย่างนี้บันทึกไฟล์ MP3 และใช้เครดิต Audinote ของคุณ

  1. สร้างคีย์ API ที่บัญชี → API และคัดลอกคีย์ลับขณะที่แสดงอยู่
  2. ตั้งค่า AUDINOTE_API_KEY ในสภาพแวดล้อมของเซิร์ฟเวอร์หรือเทอร์มินัล อย่าใส่ในโค้ดฝั่งผู้ใช้
  3. รันคำสั่งด้านล่าง แล้วเล่นไฟล์ speech.mp3
export AUDINOTE_API_KEY='<your-key>'
curl https://audinote.app/api/v1/audio/speech \
  -H "Authorization: Bearer $AUDINOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"audinote-tts-v1","input":"สวัสดี","voice":"sai-th","response_format":"mp3"}' \
  --output speech.mp3

ถ้าต้องการลองโดยไม่เขียนโค้ด ให้เปิด ทดลองใช้ API

การยืนยันตัวตนและคีย์

Base URL: https://audinote.app/api/v1 ทุกคำขอรายการโมเดลและเสียงต้องส่งคีย์ Audinote แบบ Bearer ในส่วนหัว Authorization คุกกี้ของเบราว์เซอร์ใช้ยืนยันตัวตนกับ API นี้ไม่ได้

Authorization: Bearer $AUDINOTE_API_KEY

สมาชิกสร้างและเพิกถอนคีย์ที่ใช้งานอยู่ได้สูงสุด 5 คีย์ในบัญชี → API คีย์ลับจะแสดงเพียงครั้งเดียว รายการคีย์แสดงชื่อ คำนำหน้า วันที่สร้าง และการใช้ล่าสุด การเพิกถอนจะบล็อกคำขอใหม่ อย่าใส่คีย์ใน URL ที่เก็บข้อมูลเบราว์เซอร์ หรือคลังโค้ดสาธารณะ

ส่วนหัว Idempotency-Key สำหรับ HTTP ถอดเสียงและสร้างเสียงเป็นทางเลือก ใช้อักษร ตัวเลข จุด ขีดล่าง หรือขีดกลาง 1–128 ตัว หากใช้ซ้ำกับคีย์และปลายทางเดิมจะได้ 409 duplicate_request โดยไม่ส่งผลลัพธ์เดิมซ้ำ จำกัด 60 คำขอต่อคีย์และ 120 คำขอต่อผู้ใช้ต่อนาที

โมเดลและเสียง

ผลลัพธ์รายการเป็นอาร์เรย์ data และแสดงเฉพาะชื่อ Audinote ที่เปิดใช้งาน ทั้งสองปลายทางต้องใช้คีย์ Bearer โมเดลสร้างเสียงแสดง MP3 สำหรับ HTTP และ PCM สำหรับเรียลไทม์

  • GET /api/v1/models — รหัสโมเดลที่เปิดใช้ ชนิดข้อมูล และรูปแบบไฟล์
  • GET /api/v1/voices — รหัสเสียงที่ใช้ได้และภาษา
curl https://audinote.app/api/v1/models -H "Authorization: Bearer $AUDINOTE_API_KEY"
{"data":[{"id":"audinote-asr-v1","object":"model","input_modalities":["audio"],"output_modalities":["text"],"formats":["wav"]},{"id":"audinote-tts-v1","object":"model","input_modalities":["text"],"output_modalities":["audio"],"formats":["mp3","pcm"]}]}
{"data":[{"id":"sai-th","name":"Sai","language":"th","model":"audinote-tts-v1"},{"id":"rin-en","name":"Rin","language":"en","model":"audinote-tts-v1"}]}

audinote-asr-v1 · audinote-tts-v1 · sai-th · rin-en

ถอดเสียง

POST /api/v1/audio/transcriptions

ส่ง JSON ที่มีข้อมูล WAV แบบ base64 ดิบ ไฟล์ต้องเป็น mono PCM16 ที่ 16 หรือ 24 kHz ยาวไม่เกิน 10 นาที และขนาดหลังถอดรหัสไม่เกิน 20 MiB อย่าใส่คำนำหน้า data URL ฟิลด์ที่ไม่รองรับจะถูกปฏิเสธ

AUDIO_B64=$(base64 < audio.wav | tr -d '\n')
curl https://audinote.app/api/v1/audio/transcriptions \
  -H "Authorization: Bearer $AUDINOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"audinote-asr-v1\",\"input_audio\":{\"data\":\"$AUDIO_B64\",\"format\":\"wav\"},\"language\":\"th\",\"response_format\":\"verbose_json\"}"
ฟิลด์จำเป็นความหมาย
modelใช่audinote-asr-v1
input_audioใช่ออบเจ็กต์ที่มี data (base64 ดิบ) และ format: wav
languageไม่th หรือ en; ไม่ใส่เพื่อให้ตรวจจับอัตโนมัติ
response_formatไม่json (ค่าเริ่มต้น) หรือ verbose_json

งานถอดเสียงแบบรอผล

ตรวจสอบ file_mode และ max_file_seconds จาก /models หากได้รับ async_required ให้ส่งข้อมูลเสียงแบบเดียวกันไปยัง transcription-jobs โดยไม่ส่ง response_format ใช้ Idempotency-Key ที่ไม่ซ้ำสำหรับแต่ละงาน แล้วตรวจสอบ status_url ด้วยคีย์เดิมจนได้ completed หรือ failed งานหมดอายุใน 24 ชั่วโมง ผลลัพธ์ระบุช่วงเวลาระดับไฟล์เมื่อไม่มีเวลาจากผู้ให้บริการ และ speaker เป็น null เมื่อไม่มีการแยกผู้พูด

POST /api/v1/audio/transcription-jobs
GET /api/v1/audio/transcription-jobs/:id
{ "id": "...", "status": "pending", "status_url": "/api/v1/audio/transcription-jobs/..." }

ผลลัพธ์

{
  "text": "สวัสดี",
  "model": "audinote-asr-v1",
  "usage": { "audio_seconds": 2.4, "billed_minutes": 1 },
  "duration": 2.4,
  "language": "th",
  "segments": [{ "text": "สวัสดี", "start": 0, "end": 2.4, "speaker": "speaker_1" }]
}

ผลลัพธ์มี text, model และ usage.audio_seconds / usage.billed_minutes เสมอ แบบ verbose_json เพิ่ม duration, language และ segments ตามลำดับเวลา ซึ่งมี text, start, end และชื่อผู้พูดสาธารณะ ถ้าไม่ได้ระบุ language ค่าในผลลัพธ์แบบละเอียดจะเป็น null

สร้างเสียงพูด

POST /api/v1/audio/speech

ส่ง JSON และรับข้อมูล MP3 ดิบ บันทึกเนื้อหาผลลัพธ์เป็นไฟล์หรือเล่นได้ทันที ผลลัพธ์ HTTP จำกัดขนาด 8 MiB

curl https://audinote.app/api/v1/audio/speech \
  -H "Authorization: Bearer $AUDINOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"audinote-tts-v1","input":"สวัสดี","voice":"sai-th","response_format":"mp3"}' \
  --output speech.mp3
ฟิลด์จำเป็นความหมาย
modelใช่audinote-tts-v1
inputใช่ข้อความ Unicode 1–2,000 อักขระ
voiceใช่sai-th / rin-en
response_formatไม่mp3 (ค่าเริ่มต้น) หรือ wav ตามรูปแบบที่ /models รองรับ

คำขอที่สำเร็จส่ง audio/mpeg ไม่ใช่ JSON ส่วนหัว X-Audinote-Billed-Minutes แสดงจำนวนเครดิต Audinote ที่คิดสำหรับคำขอนี้

Content-Type: audio/mpeg
X-Request-Id: <request-id>
X-Audinote-Billed-Minutes: <credits-charged>
Cache-Control: no-store

WebSocket แบบเรียลไทม์

ไคลเอนต์ที่ไม่ใช่เบราว์เซอร์เชื่อม WebSocket ASR หรือ TTS โดยส่งคีย์ Bearer ในส่วนหัว Authorization เบราว์เซอร์ตั้งส่วนหัวนี้ไม่ได้ จึงต้องขอตั๋วใช้ครั้งเดียวจากแบ็กเอนด์ของคุณ

curl https://audinote.app/api/v1/realtime/tickets \
  -H "Authorization: Bearer $AUDINOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"tts"}'

POST /realtime/tickets ส่งกลับ { ticket, expires_in: 60 } ระบุ kind เป็น asr หรือ tts ส่งตั๋วให้เบราว์เซอร์ผ่านระบบยืนยันตัวตนของคุณ แล้วใช้ audinote-ticket.<ticket> เป็น WebSocket subprotocol URL /your-app/audinote-ticket ในตัวอย่างหมายถึงปลายทางแบ็กเอนด์ที่คุณสร้างและยืนยันตัวตนเอง ตั๋วผูกกับปลายทางนั้นและถูกใช้เมื่อเชื่อมต่อ อย่าใส่คีย์หรือตั๋วใน URL

const { ticket } = await fetch("/your-app/audinote-ticket").then(r => r.json());
const ws = new WebSocket("wss://audinote.app/api/v1/realtime/tts",
  [`audinote-ticket.${ticket}`]);
ws.binaryType = "arraybuffer";
ws.onopen = () => {
  ws.send(JSON.stringify({ type: "text.append", text: "สวัสดี", voice: "sai-th" }));
  ws.send(JSON.stringify({ type: "text.commit" }));
};
ws.onmessage = event => {
  if (typeof event.data === "string") console.log(JSON.parse(event.data));
  else console.log("PCM16 bytes", event.data);
};
  • WS /api/v1/realtime/asr — รับ session.ready; ส่งไบนารี mono PCM16 ที่ 24 kHz (แนะนำเฟรมละ 80 ms) รับ speech.start, transcript.partial, transcript.final, speaker, speech.end และ usage ส่ง input_audio.commit เพื่อแบ่งช่วง หรือ session.close เพื่อจบ
  • WS /api/v1/realtime/tts — รับ session.ready; ส่ง text.append ที่มี text และ voice แล้วส่ง text.commit รับ text.committed, ข้อมูล audio.chunk ตามด้วยไบนารี PCM16 ที่ 44.1 kHz, audio.done และ usage ส่ง session.close เพื่อจบก่อนเวลา
{"type":"session.ready","session_id":"...","model":"audinote-asr-v1","audio_format":"pcm_s16le","sample_rate":24000,"max_duration_seconds":3600}
{"type":"transcript.final","turn_id":1,"text":"สวัสดี"}
{"type":"usage","audio_seconds":2.4,"billed_minutes":1}

ASR ใช้ได้สูงสุดหนึ่งชั่วโมงและปิดเมื่อไม่มีเสียง 5 วินาทีหลังเริ่มสตรีม TTS ใช้ได้สูงสุด 5 นาทีและรับข้อความไม่เกิน 2,000 อักขระโดยใช้เสียงเดียว ขนาดข้อความควบคุมและเฟรมเสียงมีขีดจำกัด ข้อมูลที่ระบบรับไปแล้วอาจถูกคิดเครดิตแม้การเชื่อมต่อหลุด

เครดิตและการใช้งาน

คำขอ API ใช้เครดิต Audinote เดิมของคุณ การถอดเสียงนับตามนาทีเสียงที่เริ่มใช้ ส่วนการสร้างเสียงนับตามข้อความ Unicode ทุก 1,000 อักขระที่เริ่มใช้ ผู้ดูแลระบบกำหนดอัตราเครดิตของแต่ละโมเดลที่เปิดใช้งาน และแสดงในหน้าตั้งค่า API ข้อมูลเรียลไทม์ที่รับไปประมวลผลแล้วอาจถูกคิดเครดิตแม้การเชื่อมต่อจะหลุดภายหลัง

ชื่อโมเดลและเสียงสาธารณะเป็นชื่อของ Audinote เอง API ไม่เปิดเผยผู้ให้บริการหรือรหัสโมเดลและเสียงต้นทาง บันทึกการใช้งานมีจำนวนหน่วย เครดิต สถานะ และเวลา โดยไม่เก็บเสียงหรือข้อความที่ส่งผ่าน API

เปิดการตั้งค่าและตัวอย่าง API

ข้อผิดพลาดและขีดจำกัด

ข้อผิดพลาดของเส้นทาง Audio API ส่ง JSON ที่มี error.code, error.message, error.type และ request_id หากขนาดคำขอใหญ่เกินกำหนดและถูกปฏิเสธก่อนถึงเส้นทาง จะได้ code: payload_too_large ที่ระดับบนสุด ให้ใช้ code จัดการข้อผิดพลาด และเก็บ request_id เมื่อมีให้ ข้อผิดพลาดเรียลไทม์จะส่ง session.error พร้อม code ก่อนปิด socket เมื่อทำได้

{ "error": { "code": "insufficient_credits", "message": "insufficient credits", "type": "invalid_request_error" }, "request_id": "..." }

สถานะที่พบบ่อย: 400 คำขอ/เสียง/ชื่อเสียงไม่ถูกต้อง; 401 ไม่มีคีย์หรือคีย์ถูกเพิกถอน; 402 insufficient_credits; 409 duplicate_request; 413 payload_too_large; 426 upgrade_required; 429 rate_limited; 502 ประมวลผลเสียงล้มเหลว; 503 บริการไม่พร้อมหรือการคิดเครดิตยังไม่เสร็จ

คำตอบ HTTP ที่ถึงเส้นทาง API สาธารณะมี X-Request-Id เก็บไว้พร้อมสถานะและรหัสข้อผิดพลาดเมื่อแก้ปัญหา ดูอัตราเครดิตปัจจุบันที่บัญชี → API