المرجع
ما تحتاجه أثناء البناء: شكل الأخطاء ورموزها، ونطاقات المفاتيح، والحدود، وصيغ الصوت، وروابط العقد الكامل.
الأخطاء
كل خطأ بالشكل نفسه. الرسالة في مسارات الجلسات عربية قابلة للعرض للمستخدم مباشرة، وrequest_id يربط الطلب بسجلاتنا (ويعود أيضاً في ترويسة X-Request-ID).
{
"error": {
"code": "ORIGIN_DENIED",
"message": "هذا الموقع غير مصرّح له باستخدام المساعد.",
"request_id": "7ef58a6c4817476f88141957853400a7"
}
}| الرمز | HTTP | يُعاد؟ | المعنى وما تفعله |
|---|---|---|---|
| AUTH_FAILED | 401 | لا | الرمز مفقود أو غير صالح، أو معرّف التضمين غير صحيح. |
| TOKEN_EXPIRED | 401 | لا | انتهت مدة رمز الجلسة. اطلب رمزاً جديداً وافتح جلسة بنفس conversation_id. |
| ORIGIN_DENIED | 403 | لا | النطاق غير مسجل، أو لا يطابق النطاق الذي صدر له الرمز. |
| TENANT_MISMATCH | 403 | لا | الجلسة لا تتبع هذه المساحة. |
| TOKEN_REPLAYED | 409 | لا | الرمز فتح جلسة من قبل. كل رمز يفتح جلسة واحدة. |
| IDEMPOTENCY_CONFLICT | 409 | لا | المفتاح استُخدم من قبل. استخدم مفتاحاً جديداً. |
| STALE_GENERATION | 409 | لا | رد قديم تُجوهل بعد مقاطعة أو إيقاف. |
| CONVERSATION_NOT_FOUND | 404 | لا | الجلسة غير موجودة أو انتهت (ومنه بعد إعادة تشغيل صُرَد). اطلب رمزاً جديداً وافتح جلسة بنفس conversation_id. |
| NO_PUBLISHED_AGENT | 404 | لا | الوكيل غير منشور، أو التضمين غير مفعّل في المراجعة المنشورة. |
| VALIDATION_FAILED | 422 | لا | الطلب ناقص أو غير صالح. |
| AUDIO_EMPTY | 400 | لا | ملف الصوت فارغ أو غير صالح. |
| RATE_LIMITED | 429 | نعم | تجاوزت حد الاستخدام. أعد المحاولة بعد لحظات. |
| BUDGET_EXHAUSTED | 429 | لا | انتهت الحصة المخصصة. |
| AUDIO_PRODUCTION_FAILURE | 502 | نعم | تعذّر تحميل إعدادات صوت الوكيل. أعد مرة بمفتاح جديد، ثم اكتفِ بالنص. |
| INTERNAL | 500 | لا | خطأ غير متوقع. أرسل request_id إلى الدعم. |
أخطاء مفاتيح API
| الحقل | النوع | الوصف |
|---|---|---|
AUTHENTICATION_FAILED | 401 | المفتاح مفقود أو غير صحيح. |
API_KEY_REVOKED | 401 | المفتاح أُلغي. أنشئ مفتاحاً جديداً من Studio ← الدمج. |
SCOPE_DENIED | 403 | المفتاح لا يحمل النطاق اللازم لهذا الطلب. |
INVALID_SCOPES | 422 | نطاق غير معروف عند إنشاء المفتاح. |
QUOTA_EXCEEDED | 429 | تجاوز المفتاح حصته (لا يُرفع في وضع المراقبة فقط). |
BUDGET_EXCEEDED | 429 | تجاوزت تكلفة المفتاح ميزانية باقته (في الباقات التي تمنع التجاوز). |
WORKSPACE_QUOTA_EXCEEDED | 422 | امتلأت مساحة تخزين الصوت المخصصة لمساحة العمل. |
متى تعيد المحاولة
- أعد المحاولة فقط لما يُعاد (
RATE_LIMITED،AUDIO_PRODUCTION_FAILURE، وانقطاع الشبكة)، بتأخير متزايد قصير. بعد فشل مسجل (audio: nullأوAUDIO_PRODUCTION_FAILURE) أعدبمفتاحidempotency_keyجديد؛ وبعد انقطاع الشبكة يكفي المفتاح نفسه. المفتاح يعرّف تنفيذاً واحداً في مساحة العمل كلها، وتكرار المفتاح لا ينطق من جديد ولا يكلّف شيئاً. إن كان الطلب الأول قد اكتمل في المحادثة والجيل نفسيهما خلال آخر 10 دقائق، يعود صوته الأصلي (idempotent_replay: true). وفي غير ذلك (فشل، أو ما زال قيد التنفيذ، أو مضت المدة، أو المفتاح لمحادثة أخرى) يعود بلا صوت ومعهrequires_new_idempotency_key: true، فأرسل مفتاحاً جديداً. - فشل المزوّد في نطق رد لا يعيد خطأ HTTP: يعود الدور 200 ومعه
audio: nullوfailed: trueوerror_code، والنص كاملاً. أعد مرة بمفتاح جديد، ثم اعرض النص. 404 CONVERSATION_NOT_FOUND: الجلسات الحية تُحفظ في عملية الخادم، فتنتهي بإعادة تشغيله. اطلب رمزاً جديداً وافتح جلسة بنفسconversation_id؛ السجل محفوظ.401 TOKEN_EXPIRED: اطلب رمزاً جديداً من خادمك، وافتح جلسة بنفسconversation_id، ثم أعد الطلب.- لا تُعد طلباً أعاد 4xx آخر قبل تصحيحه؛ النتيجة ستتكرر.
- إن تعذّر الصوت بعد محاولة واحدة، اعرض الرد نصاً: النص يعود دائماً مع الدور حتى إن فشل الصوت.
نطاقات مفاتيح API
تختار النطاقات عند إنشاء المفتاح. امنح المفتاح أقل ما يحتاجه.
| الحقل | النوع | الوصف |
|---|---|---|
sessions.create | scope | إصدار رموز الجلسات (الاستخدام الأساسي لخادم موقعك). |
sessions.stream | scope | قنوات البث للجلسات. |
speech.transcribe | scope | تحويل الكلام إلى نص. |
speech.synthesize | scope | نطق النصوص. |
agents.read | scope | قراءة الوكلاء وسجل المحادثات. |
agents.manage | scope | إدارة الوكلاء وتشغيلهم. |
tools.ack | scope | تأكيد نتائج الأدوات. |
usage.read | scope | قراءة الاستخدام. |
الحدود
| الحقل | النوع | الوصف |
|---|---|---|
رمز الجلسة | 60–3600 s | الافتراضي 900 ثانية. رمز التضمين العام 600 ثانية. |
جلسات التضمين العام | rate | 20 لكل زائر كل 10 دقائق، و600 لكل وكيل في الساعة. |
مفتاح API | rpm | الافتراضي 120 طلباً في الدقيقة، ويُضبط لكل مفتاح. |
رفع الصوت | 4 MB | حد ملف الرسالة الصوتية. |
تسجيل الويدجت | 30 s | أقصى مدة للرسالة الصوتية من الويدجت. |
سجل المحادثات | ≤ 100 | محادثات في الصفحة الواحدة. |
صيغ الصوت
| الحقل | النوع | الوصف |
|---|---|---|
إلى صُرَد | WAV | الأنسب: أحادي، 16kHz، PCM16. |
من صُرَد (كامل) | WAV | في audio.content_base64. |
من صُرَد (بث) | PCM16 | أجزاء خام في audio.chunk: LINEAR16، 24kHz، أحادي، بترتيب seq. |
هوية التنفيذ
كل دور منطوق يعيد ما نُفّذ فعلاً، لتتحقق من ثبات صوت وكيلك. audio.executed_voice (الصوت الذي نطق) موجود في كل المسارات، ومعه ملف صوت الوكيل: identity.voice_profile_id في أدوار عقل صُرَد، وidentity.executed_profile_id في النطق للنص الجاهز. وإن تعذّر تحميل صوت الوكيل يعود خطأ صريح، ولا يُنطق الرد بصوت آخر.
أمثلة استجابات حقيقية
مأخوذة من تشغيل فعلي للـAPI (قُصّرت المعرّفات).
{
"token": "eyJ…",
"claims": {
"workspace_id": "01a14abf-891e-…",
"agent_id": "01a14abf-9774-…",
"agent_version_id": null,
"origin": "https://www.example.com",
"channel": "web_widget",
"exp": 1792256333,
"scopes": ["widget.session", "speech.transcribe", "speech.synthesize"],
"ttl_seconds": 900
}
}POST /api/v1/widget/sessions (الرمز نفسه مرة ثانية)
409
{ "error": { "code": "TOKEN_REPLAYED", "message": "طلب مكرر. أعد فتح الجلسة.", "request_id": "9ee729a8…" } }الاستهلاك والقياس
يُقاس كل طلب ومدة الاستماع والنطق لكل مفتاح، وتُعرض التكلفة في Studio ← الاستخدام. الوضع الافتراضي «مراقبة فقط»: تُسجَّل الحصة ولا يُوقَف الطلب. أما الباقات التي تمنع التجاوز فتعيد QUOTA_EXCEEDED أو BUDGET_EXCEEDED.
GET /api/v1/workspaces/{workspace_id}/developer/usage (مفتاح بنطاق usage.read)
{
"request_count": 1,
"used_units": 1,
"quota_units": 10000,
"remaining_units": 9999,
"budget_cents": 0,
"speech_jobs": 0,
"usage_cap_mode": "MONITOR_ONLY",
"overage_policy": "MONITOR",
"quota_utilization_pct": 0.0,
"quota_state": "ok"
}منع التكرار
أرسل idempotency_key جديداً (UUID) لكل طلب. تكرار المفتاح لا ينطق من جديد ولا يكلّف شيئاً. إن كان الطلب الأول قد اكتمل في المحادثة والجيل نفسيهما خلال آخر 10 دقائق، يعود صوته الأصلي (idempotent_replay: true). وفي غير ذلك (فشل، أو ما زال قيد التنفيذ، أو مضت المدة، أو المفتاح لمحادثة أخرى) يعود بلا صوت ومعه requires_new_idempotency_key: true، فأرسل مفتاحاً جديداً. وبعد إيقاف الرد لا يُعاد صوته القديم.
تشخيص مشاكل التكامل
| الحقل | النوع | الوصف |
|---|---|---|
403 ORIGIN_DENIED | النطاق | سجّل نطاقك حرفياً (https و www كما في شريط العنوان)، وأرسل Origin نفسه الذي صدر له الرمز. |
409 TOKEN_REPLAYED | الرموز | لا تُعد استخدام رمز لفتح جلسة ثانية: اطلب رمزاً جديداً لكل فتح. |
401 TOKEN_EXPIRED | الرموز | اطلب رمزاً جديداً، وافتح جلسة بنفس conversation_id لتكمل المحادثة. |
404 NO_PUBLISHED_AGENT | الوكيل | انشر الوكيل، ثم تأكد أن الجلسة تفتح بعد النشر لا قبله. |
لا صوت في الرد | شكل الرد | تحقق من «شكل الرد»: «نص فقط» لا يولّد صوتاً، والنص يعود في reply.display. |
الصوت مختلف عن المتوقع | الصوت | قارن audio.executed_voice بما اخترته في Studio، وتأكد أنك نشرت المراجعة التي غيّرت فيها الصوت. |
لا تصل أحداث البث | البث | افتح قناة الأحداث قبل طلب النطق، واقرأها بـ fetch لا EventSource، وتأكد أن البث مفعّل لمساحتك. |
بطء غير معتاد | الأداء | افصل زمنك عن زمننا: سجّل t0 وaudio.first وبدء التشغيل، وأرسل لنا request_id أو idempotency_key. |
ولأي مشكلة أخرى أرسل request_id (من جسم الخطأ أو ترويسة X-Request-ID)، فهو يربط طلبك بسجلاتنا مباشرة.
العقد الكامل والأدوات
- OpenAPI (حي، يطابق الإنتاج دائماً):
https://app.surad-ai.com/api/v1/developer-kit/v1/openapi.json - حزمة المطور (أمثلة curl وNode وPython وLaravel وWordPress، ومجموعة Postman، وحزم SDK):
https://app.surad-ai.com/api/v1/developer-kit/v1 - لوكلاء البرمجة بالذكاء الاصطناعي:
/llms.txtو/llms-full.txt
/openapi.json في جذر النطاق محجوب عمداً. استخدم رابط حزمة المطور أعلاه.