نشانی اصلی: wss://gisoo.pro/api/v1/realtime؛ نشانی ویژهٔ ایران: wss://ir.gisoo.pro/api/v1/realtime. پارامترها و کلید دسترسی در هر دو یکساناند.
با اتصال زنده (Realtime) یک گفتوگوی صوتی دوطرفه روی یک اتصال WebSocket دارید: صدای کاربر را همان لحظه که حرف میزند میفرستید و پاسخ مدل را تکهتکه، هم بهصورت صدا و هم متن، پس میگیرید. بیشتر برای تلفن گویا و دستیار صوتی به کار میرود: منشی تلفنی، ثبت سفارش تلفنی یا پاسخگوی مرکز تماس. پروتکل با OpenAI Realtime API (نام رویدادهای نسخهٔ نهایی یا GA) سازگار است، پس کد و کتابخانهای که برای آن نوشته شده با عوض کردن نشانی و کلید کار میکند.
این نشانی از سرورهای داخل ایران هم در دسترس است. کلید، اعتبار و گزارش مصرف همان است که در درخواستهای HTTP دارید. درخواست ارتقا به WebSocket یک درخواست GET است.
چطور کار میکند
-
اتصال
سرور شما با هدر
Authorization: Bearer <کلید>به نشانی بالا وصل میشود و مدل را در پارامترmodelمیگوید. پیامsession.createdیعنی جلسه باز است. -
تنظیم جلسه
با
session.updateدستور سیستمی (instructions)، قالب صدا، صدای گوینده و ابزارها را تعیین میکنید. -
فرستادن صدا
صدای کاربر را تکهتکه با
input_audio_buffer.appendمیفرستید. بهطور پیشفرض سرویس خودش پایان حرف را تشخیص میدهد (server_vad) و پاسخ را شروع میکند. -
گرفتن پاسخ
صدای پاسخ در
response.output_audio.deltaو متن همان پاسخ درresponse.output_audio_transcript.deltaمیرسد. اگر مدل ابزاری را صدا بزند، شما تابع خودتان را اجرا میکنید و نتیجه را برمیگردانید.
دو نوع مدل روی اتصال زنده کار میکند. مدلهای گفتاری مستقیم (GPT Realtime و Gemini Live) صدا را خودشان میشنوند و خودشان با صدا جواب میدهند؛ مکث پیش از پاسخ در آنها کوتاهتر است و برای پاسخگوی تلفنی و فروش تلفنی مناسبترند. در بقیهٔ مدلها خروجی مدل متن است. وقتی خروجی صوتی روشن است، سرویس همان متن را تکهبهتکه به گفتار تبدیل میکند و اول عبارت کوتاهی میفرستد تا کاربر شروع پاسخ را بشنود و بقیهاش در همان حال نوشته شود. در این حالت یک دستور کوتاه هم به دستور سیستمی شما اضافه میشود تا مدل با جملههای ساده و گفتاری جواب بدهد، بدون Markdown، فهرست یا ایموجی.
اتصال و احراز هویت
- کلید را در هدر
Authorization: Bearer …یاX-API-Keyبفرستید؛ همان کلیدی که برای درخواستهای HTTP دارید (sk-gisoo-v1-…یاsk-ntz-v1-…). - کلید پیش از باز شدن اتصال بررسی میشود، درست مثل یک درخواست HTTP: باطل یا منقضی یا غیرفعال بودن کلید، فهرست IPهای مجاز و فهرست مدلهای مجاز کلید و پروژه.
- اگر اتصال پذیرفته نشود، WebSocket باز نمیشود و یک پاسخ HTTP معمولی (۴۰۱، ۴۰۲، ۴۰۳، ۴۲۹ یا ۵۰۳) با همان قالب خطای
{"error": {...}}میگیرید. - مدل را در نشانی انتخاب میکنید و تا پایان جلسه عوض نمیشود.
- پارامتر اختیاری
codecقالب صدای ورودی و خروجی را از همان لحظهٔ اتصال تعیین میکند:alawوulaw(G.711 با ۸ کیلوهرتز، همان چیزی که Asterisk میدهد)،pcm8،pcm16وpcm24(PCM شانزدهبیتی با ۸، ۱۶ یا ۲۴ کیلوهرتز). مقدار ناشناخته خطای ۴۰۰invalid_codecمیدهد.
مرورگر نمیتواند هدر Authorization را روی WebSocket بگذارد و کلید هم نباید به دست کاربر برسد. این API برای ارتباط سرور با سرور است: مرورگر یا اپ شما به سرور خودتان وصل میشود و سرور شما به گیسو.
HTTP/1.1 402 Payment Required
Content-Type: application/json; charset=utf-8
{"error": {"message": "…", "type": "insufficient_quota", "code": "insufficient_credit", "param": null}}
مدلها
| شناسهٔ مدل | سازنده | نوع | مناسب برای |
|---|---|---|---|
gpt-realtime-2.1 | OpenAI | گفتاری مستقیم | فروش و پشتیبانی تلفنی، وقتی کیفیت گفتوگو از هزینه مهمتر است |
gpt-realtime-2.1-mini | OpenAI | گفتاری مستقیم | بیشتر تماسها؛ کمهزینهتر از نسخهٔ کامل |
gemini-3.8-live | گفتاری مستقیم | گفتوگوی طبیعی فارسی با هزینهٔ کمتر از GPT Realtime | |
qwen3.8-omni-flash-realtime | Alibaba (Qwen) | گفتاری مستقیم | پاسخگوی تلفنی فارسی با مکث کوتاه و هزینهٔ کم |
qwen/qwen3.8-omni-flash | Qwen | متن، سپس تبدیل به گفتار | آزمایش و تماسهای ساده |
- مدلهای گفتاری مستقیم فقط روی همین اتصال کار میکنند؛ برای همین در فهرست
GET /modelsنیستند و در/chat/completionsپذیرفته نمیشوند. - صدای گوینده را در
audio.output.voiceبدهید: در GPT Realtime یکی از صداهای OpenAI (مثلmarin،cedarیاalloy) و در Gemini Live یکی از صداهای Gemini (مثلKore،Puck،CharonیاAoede). در Gemini Live نام ناشناخته صدایKoreرا میگیرد. در Qwen Realtime صدای پیشفرضTinaاست و نام صداهای OpenAI همان صدای پیشفرض را میگیرد. - در
qwen3.8-omni-flash-realtimeتصویر فقط JPEG (به شکلdata:image/jpeg;base64,…) پذیرفته میشود،tool_choiceو تنظیمات جداگانه درresponse.createاثری ندارند، وconversation.item.truncateفقط تأیید میشود: پاسخ قطعشده در حافظهٔ گفتوگوی مدل کامل میماند. - در Gemini Live دستور سیستمی، صدا و ابزارها را در همان اولین
session.updateبدهید. تغییرشان در میانهٔ جلسه هم پذیرفته میشود، ولی اتصال به مدل از نو برقرار میشود و ممکن است یک لحظه مکث بشنوید. پیامهایconversation.item.createدر Gemini Live فقط متن میپذیرند؛ صدا را باinput_audio_buffer.appendبفرستید.
از مدلهای دیگر، هر مدل گفتوگوی فعالی که ورودی صوتی بپذیرد کار میکند. پیشنهاد ما qwen/qwen3.8-omni-flash است؛ شناسهٔ کاملش openrouter/qwen/qwen3.8-omni-flash است و نام کوتاه هم به همان مدل میرسد.
مدلی که ورودی صوتی ندارد، پیش از باز شدن اتصال خطای model_not_realtime میگیرد. فهرست مدلها در صفحهٔ مدلها است.
نمونهٔ کامل: پاسخگوی تلفنی با ثبت سفارش
این نمونه صدای تماس را با قالب A-law میفرستد و میگیرد، متن پاسخ را ثبت میکند، وقتی کاربر وسط حرف دستیار شروع به صحبت کند پخش را قطع میکند، و سفارش را با ابزار place_order ثبت میکند. شیء call نمایندهٔ خط تلفن در برنامهٔ شماست.
برای سرورها و کاربران داخل ایران، در این نمونه نشانی gisoo.pro را با ir.gisoo.pro جایگزین کنید؛ مسیر و کلید هماناند.
// npm install ws
import WebSocket from "ws";
const URL = "wss://gisoo.pro/api/v1/realtime?model=qwen/qwen3.8-omni-flash&codec=alaw";
const ws = new WebSocket(URL, {
headers: { Authorization: `Bearer ${process.env.GISOO_API_KEY}` },
});
// A refused connection (bad key, no credit, wrong model…) is a plain HTTP response.
ws.on("unexpected-response", (req, res) => {
let body = "";
res.on("data", (chunk) => (body += chunk));
res.on("end", () => console.error("refused:", res.statusCode, body));
});
ws.on("open", () => {
ws.send(JSON.stringify({
type: "session.update",
session: {
instructions: "You answer the phone for a pizza shop. Speak Persian, short and polite.",
audio: { output: { voice: "alloy" } },
tools: [{
type: "function",
name: "place_order",
description: "Register the caller's order once items and address are confirmed.",
parameters: {
type: "object",
properties: {
items: { type: "array", items: { type: "string" } },
address: { type: "string" },
},
required: ["items", "address"],
},
}],
},
}));
// `call` is your telephony leg (e.g. Asterisk AudioSocket): raw A-law 8 kHz frames.
call.on("audio", (frame) => {
ws.send(JSON.stringify({ type: "input_audio_buffer.append", audio: frame.toString("base64") }));
});
});
ws.on("message", async (data) => {
const event = JSON.parse(data);
switch (event.type) {
case "response.output_audio.delta":
call.play(Buffer.from(event.delta, "base64")); // already A-law: no conversion
break;
case "input_audio_buffer.speech_started":
call.stopPlayback(); // the caller is talking over the answer
break;
case "response.output_audio_transcript.done":
console.log("assistant:", event.transcript);
break;
case "response.function_call_arguments.done": {
const args = JSON.parse(event.arguments);
const result = await placeOrder(args); // your own code
ws.send(JSON.stringify({
type: "conversation.item.create",
item: { type: "function_call_output", call_id: event.call_id, output: JSON.stringify(result) },
}));
ws.send(JSON.stringify({ type: "response.create" }));
break;
}
case "error":
console.error(event.error.code, event.error.message);
break;
}
});
ws.on("close", (code, reason) => console.log("closed", code, reason.toString()));
# pip install websockets (v14+; older versions name the argument extra_headers)
import asyncio, base64, json, os
import websockets
URL = "wss://gisoo.pro/api/v1/realtime?model=qwen/qwen3.8-omni-flash&codec=alaw"
PLACE_ORDER = {
"type": "function",
"name": "place_order",
"description": "Register the caller's order once items and address are confirmed.",
"parameters": {
"type": "object",
"properties": {
"items": {"type": "array", "items": {"type": "string"}},
"address": {"type": "string"},
},
"required": ["items", "address"],
},
}
async def run(call):
headers = {"Authorization": f"Bearer {os.environ['GISOO_API_KEY']}"}
async with websockets.connect(URL, additional_headers=headers) as ws:
await ws.send(json.dumps({"type": "session.update", "session": {
"instructions": "You answer the phone for a pizza shop. Speak Persian, short and polite.",
"tools": [PLACE_ORDER],
}}))
async def caller_audio():
async for frame in call.frames(): # raw A-law 8 kHz bytes
await ws.send(json.dumps({"type": "input_audio_buffer.append",
"audio": base64.b64encode(frame).decode()}))
sender = asyncio.create_task(caller_audio())
try:
async for message in ws:
event = json.loads(message)
kind = event["type"]
if kind == "response.output_audio.delta":
call.play(base64.b64decode(event["delta"]))
elif kind == "input_audio_buffer.speech_started":
call.stop_playback()
elif kind == "response.output_audio_transcript.done":
print("assistant:", event["transcript"])
elif kind == "response.function_call_arguments.done":
result = place_order(**json.loads(event["arguments"])) # your own code
await ws.send(json.dumps({"type": "conversation.item.create", "item": {
"type": "function_call_output",
"call_id": event["call_id"],
"output": json.dumps(result),
}}))
await ws.send(json.dumps({"type": "response.create"}))
elif kind == "error":
print("error:", event["error"]["code"], event["error"]["message"])
finally:
sender.cancel()
# A refused connection raises websockets.exceptions.InvalidStatus;
# e.response.status_code and e.response.body hold the usual {"error": {...}} JSON.
اتصال به Asterisk
AudioSocket و ExternalMedia در Asterisk صدای تماس را به شکل slin، alaw یا ulaw با ۸ کیلوهرتز میدهند. کافی است همان قالب را در نشانی بگویید: codec=alaw یا codec=ulaw، و برای slin مقدار codec=pcm8.
آنوقت صدای تماس را بیتغییر میفرستید و صدای پاسخ را هم بیتغییر روی خط پخش میکنید؛ به تبدیل نرخ نمونهبرداری یا قالب نیازی نیست.
برنامهٔ میان Asterisk و این API (مثل نمونهٔ بالا) را خودتان مینویسید؛ ماژول آمادهای برای Asterisk نداریم.
تنظیم جلسه (session.update)
{
"type": "session.update",
"session": {
"output_modalities": ["audio"],
"instructions": "You are the receptionist of a dental clinic. Speak Persian.",
"audio": {
"input": {
"format": { "type": "audio/pcm", "rate": 16000 },
"turn_detection": {
"type": "server_vad",
"threshold": 0.5,
"prefix_padding_ms": 300,
"silence_duration_ms": 500,
"create_response": true,
"interrupt_response": true
}
},
"output": {
"format": { "type": "audio/pcm", "rate": 16000 },
"voice": "coral",
"model": "gpt-4o-mini-tts",
"instructions": "Warm, calm and unhurried."
}
},
"tools": [],
"tool_choice": "auto",
"temperature": 0.7,
"max_output_tokens": 1024,
"reasoning": { "effort": "none" }
}
}
["audio"] (پیشفرض: پاسخ گفتاری و متن آن) یا ["text"] (فقط متن).{"type":"audio/pcm","rate":8000|16000|24000} (شانزدهبیتی little-endian، تککاناله؛ پیشفرض ۲۴۰۰۰)، {"type":"audio/pcmu"} (G.711 μ-law، ۸ کیلوهرتز) یا {"type":"audio/pcma"} (G.711 A-law، ۸ کیلوهرتز). نامهای نسخهٔ بتا (pcm16، g711_ulaw، g711_alaw) هم پذیرفته میشوند.server_vad، پیشفرض) با threshold بین ۰ و ۱ (پیشفرض ۰٫۵)، prefix_padding_ms (۳۰۰)، silence_duration_ms (۵۰۰)، create_response و interrupt_response (هر دو true). با null خودتان commit و response.create میفرستید.alloy. صداهای gpt-4o-mini-tts: alloy، ash، ballad، coral، echo، fable، nova، onyx، sage، shimmer، verse.gpt-4o-mini-tts. مدلهای Gemini TTS هم کار میکنند و فارسی را طبیعیتر میخوانند، ولی هر جمله حدود ۳ ثانیه دیرتر میرسد.{"type":"function","name","description","parameters"})، حداکثر ۶۴ ابزار و ۶۴ کیلوبایت. tool_choice: auto، none، required یا {"type":"function","name":"…"}."inf".{"effort":"none"|"low"|"medium"|"high"}. پیشفرض none است، چون فکر کردن مدل پیش از پاسخ چند ثانیه به شروع جواب اضافه میکند و کاربر آن را سکوت میشنود.نوبتها و قطع کردن حرف
با server_vad سرویس پایان حرف کاربر را تشخیص میدهد، صدا را commit میکند و پاسخ میسازد.
اگر کاربر وسط ساخته شدن پاسخ شروع به حرف زدن کند، پاسخ لغو میشود (interrupt_response) و رویداد input_audio_buffer.speech_started میرسد.
پخش صدایی را که پیشتر گرفتهاید باید خودتان قطع کنید. اگر بخواهید مدل بداند کاربر تا کجای پاسخ را شنیده، conversation.item.truncate بفرستید:
{"type": "conversation.item.truncate", "item_id": "item_7Kx2…", "content_index": 0, "audio_end_ms": 1800}
اگر نوبتها را خودتان مدیریت میکنید (مثلاً با دکمهای که کاربر هنگام حرف زدن نگه میدارد، یا Push-to-talk)، تشخیص خودکار را خاموش کنید:
{"type": "session.update", "session": {"audio": {"input": {"turn_detection": null}}}}
{"type": "input_audio_buffer.append", "audio": "<base64 audio>"}
{"type": "input_audio_buffer.append", "audio": "<base64 audio>"}
{"type": "input_audio_buffer.commit"}
{"type": "response.create"}
برای پاسخ فقط متنی، یا فرستادن متن بهجای صدا:
{"type": "session.update", "session": {"output_modalities": ["text"]}}
{"type": "conversation.item.create", "item": {
"type": "message", "role": "user",
"content": [{"type": "input_text", "text": "ساعت کاری شما تا کی است؟"}]
}}
{"type": "response.create"}
فراخوانی ابزار (Function Calling)
ابزارها را در session.update تعریف میکنید. وقتی مدل ابزاری را صدا بزند، آرگومانهایش در response.function_call_arguments.done میرسد.
تابع خودتان را اجرا کنید (مثلاً سفارش را ثبت کنید)، نتیجه را با conversation.item.create و {"type":"function_call_output","call_id":…,"output":"…"} برگردانید (output یک رشتهٔ JSON است) و سپس response.create بفرستید تا مدل نتیجه را به کاربر بگوید.
چرخهٔ ابزارها همان است که در فراخوانی ابزار آمده است.
رویدادها
رویدادهای کلاینت (شما میفرستید)
| type | کار |
|---|---|
session.update | تنظیم جلسه (بخش «تنظیم جلسه» در پایین). هر وقت لازم شد دوباره بفرستید. |
input_audio_buffer.append | یک تکه صوت کاربر، base64 و با قالب ورودی جلسه. |
input_audio_buffer.commit | پایان نوبت کاربر؛ فقط وقتی تشخیص خودکار گفتار خاموش است لازم میشود. |
input_audio_buffer.clear | دور ریختن صوتی که هنوز commit نشده. |
conversation.item.create | افزودن پیام به گفتوگو: برای user با input_text یا input_audio، برای assistant و system با text؛ یا نتیجهٔ ابزار با type: function_call_output. |
conversation.item.delete | حذف یک آیتم از گفتوگو. |
conversation.item.retrieve | گرفتن یک آیتم گفتوگو. |
conversation.item.truncate | وقتی کاربر وسط پاسخ حرف زد: فقط بخشی از پاسخ را که واقعاً شنیده (تا audio_end_ms) در گفتوگو نگه میدارد. |
response.create | گرفتن پاسخ از مدل. |
response.cancel | متوقف کردن پاسخی که در حال ساخت است. |
هر رویداد دیگری خطای unsupported_event میگیرد.
رویدادهای سرور (شما میگیرید)
| type | معنا |
|---|---|
session.created / session.updated | جلسه باز شد / تنظیمات تازه پذیرفته شد (تنظیمات کامل جلسه همراهش میآید). |
input_audio_buffer.speech_started / speech_stopped | کاربر شروع به حرف زدن کرد / ساکت شد. با speech_started پخش صدای خودتان را قطع کنید. |
input_audio_buffer.committed / cleared | نوبت کاربر ثبت شد / بافر خالی شد. |
conversation.item.added / done / deleted / retrieved / truncated | تغییرات آیتمهای گفتوگو. |
response.created | ساخت پاسخ شروع شد. |
response.output_item.added / done | یک آیتم خروجی (پیام یا فراخوانی ابزار) شروع شد / تمام شد. |
response.content_part.added / done | یک بخش از محتوای پیام شروع شد / تمام شد. |
response.output_audio.delta / done | صدای پاسخ، base64 و با قالب خروجی جلسه، در قابهای حدوداً ۲۰۰ میلیثانیهای. |
response.output_audio_transcript.delta / done | متن همان پاسخ گفتاری، همزمان با نوشته شدنش. |
response.output_text.delta / done | پاسخ متنی، وقتی output_modalities برابر ["text"] است. |
response.function_call_arguments.delta / done | آرگومانهای فراخوانی ابزار؛ در done، مقدار call_id، name و arguments کامل میآید. |
response.done | پایان پاسخ با status (completed، cancelled، incomplete یا failed) و مصرف توکن. |
error | خطا؛ جلسه باز میماند مگر خود خطا بگوید بسته شده است. |
محدودیتها
| مورد | سقف |
|---|---|
| یک پیام WebSocket | ۱ مگابایت |
| سرعت فرستادن صدا | حداکثر چهار برابر زمان واقعی |
| یک نوبت گفتار | ۶۰ ثانیه |
| حافظهٔ گفتوگو | ۲۰۰ آیتم آخر؛ از صدای کاربر فقط حدود ۲ مگابایت آخر بهصورت صدا به مدل میرسد. صدای نوبتهای قدیمیتر دیگر به مدل نمیرسد، ولی متنها و پاسخها میمانند. |
| طول جلسه | یک ساعت، یا ۱۲۰ ثانیه بدون هیچ پیامی از سمت شما |
| جلسههای همزمان | ۱۰ جلسه برای هر حساب |
- هر نوبت پاسخ مثل یک درخواست معمولی حساب میشود: یکی از درخواستهای همزمان حساب و یکی از سقف درخواست در دقیقهٔ کلید را میگیرد (مدیریت هزینه و محدودیتها).
- سرور هر ۲۵ ثانیه ping میفرستد. کتابخانههای WebSocket خودشان جواب pong را میدهند و کاری لازم نیست.
- اگر کلید را باطل کنید، جلسههای باز آن کلید حداکثر حدود ۳۰ ثانیه بعد بسته میشوند.
سرعت پاسخ
در اندازهگیریهای ما با qwen/qwen3.8-omni-flash، متن پاسخ معمولاً ۳ تا ۴ ثانیه بعد از ساکت شدن کاربر شروع میشود و اولین تکهٔ گفتاری با gpt-4o-mini-tts حدود یک ثانیه بعد از آن میرسد.
این عددها تضمینی نیستند و به طول گفتوگو، مدل و شلوغی سرویسدهنده بستگی دارند. مدلهای گفتاری مستقیم (جدول «مدلها») چون صدا را خودشان میشنوند و میسازند، این مکث را ندارند و برای تماس تلفنی پیشنهاد ما همینها هستند. برای کوتاهتر شدن مکث، reasoning.effort را روی none بگذارید و در دستور سیستمی از مدل بخواهید کوتاه جواب بدهد.
هزینه
هزینهٔ اتصال زنده برای هر نوبت جدا از همان اعتبار حساب کم میشود: فراخوانی مدل یک ردیف است و هر تکهٔ گفتاری پاسخ یک ردیف جدا. همهٔ این ردیفها با برچسب Realtime (WebSocket) و Speech و با هزینهٔ دقیق هر کدام در گزارش درخواستهای اپ دیده میشوند.
در مدلهای گفتاری مستقیم هر اتصال یک ردیف است: هنگام باز شدن اتصال مبلغی از اعتبار حساب کنار گذاشته میشود، در طول گفتوگو هر وقت لازم باشد بیشتر میشود و وقتی اتصال بسته شد فقط مصرف واقعی (توکنهای صدا و متن ورودی و خروجی) کم میشود و بقیه آزاد میشود.
این ردیف بعد از بسته شدن اتصال با برچسب Realtime (WebSocket) در همان گزارش دیده میشود. اگر اعتبار در میانهٔ گفتوگو تمام شود، پیش از بسته شدن اتصال یک رویداد error با کد insufficient_credit میرسد.
حریم خصوصی
صدا و متن گفتوگو را ذخیره نمیکنیم. مثل هر درخواست دیگر API، از هر نوبت فقط شمار توکنها و هزینهاش ثبت میشود.
خطاها
پیش از باز شدن اتصال (پاسخ HTTP)
| code | HTTP | معنا و راه رفع |
|---|---|---|
missing_api_key | 401 | هدر Authorization یا X-API-Key فرستاده نشده. |
invalid_api_key | 401 | کلید نادرست است. |
api_key_revoked | 401 | کلید باطل شده، منقضی شده یا غیرفعال است. |
ip_not_allowed | 403 | IP سرور شما در فهرست IPهای مجاز کلید نیست. |
model_not_realtime | 400 | مدل ورودی صوتی ندارد؛ یک مدل گفتوگوی صوتی (مثل qwen/qwen3.8-omni-flash) انتخاب کنید. |
insufficient_credit | 402 | اعتبار حساب کافی نیست؛ اعتبار را شارژ کنید. |
realtime_session_limit | 429 | حساب شما ۱۰ جلسهٔ باز دارد؛ پیش از اتصال تازه یکی را ببندید. |
too_many_connections | 429 | از یک IP در یک دقیقه بیش از حد اتصال تازه باز شده؛ کمی صبر کنید و دوباره وصل شوید. |
invalid_codec | 400 | مقدار codec یکی از alaw، ulaw، pcm8، pcm16 یا pcm24 نیست. |
در طول جلسه (رویداد error)
{"type": "error", "error": {"type": "invalid_request_error", "code": "conversation_already_has_active_response", "message": "…", "param": null, "event_id": "evt_…"}}
| code | معنا و راه رفع |
|---|---|
unsupported_event | نوع رویداد پشتیبانی نمیشود (فهرست رویدادهای کلاینت را ببینید). |
invalid_audio_format | قالب صوتی در session.update معتبر نیست. |
input_audio_buffer_commit_empty | بافر خالی را commit کردهاید. |
input_audio_buffer_too_large | یک نوبت گفتار از ۶۰ ثانیه بیشتر شده. |
audio_rate_exceeded | صوت سریعتر از چهار برابر زمان واقعی فرستاده شده. |
conversation_already_has_active_response | پاسخ قبلی هنوز تمام نشده؛ صبر کنید یا response.cancel بفرستید. |
speech_failed | تبدیل یک تکه از پاسخ به گفتار ناموفق بود؛ متن آن در transcript هست. |
session_closed | جلسه بسته شد (یک ساعت گذشته، ۱۲۰ ثانیه پیامی نیامده، یا کلید باطل شده). |
server_restart | سرویس در حال بهروزرسانی است؛ چند ثانیه بعد دوباره وصل شوید. |
فهرست کامل کدهای خطای API در صفحهٔ خطاها است.
پاسخ پرسشتان را پیدا نکردید؟
شناسهٔ درخواست (هدر X-Request-Id) را با پرسشتان در تیکت بفرستید تا دقیق بررسی کنیم.