الرابط الأساسي https://api.echonova.ai

المطورون

الأخطاء

كل حالة HTTP وكل errorMessage تعيدها واجهة API الإصدار v1، ومتى يحدث كل منها، وما الذي تفعله حياله، وكيف تبلغ المهام غير المتزامنة عن فشلها.

تسرد هذه الصفحة كل خطأ تعيده نقاط النهاية في /v1: رمز HTTP، وerrorMessage بالنص الحرفي، والشرط الذي يطلقه، والإصلاح. وهي للمهندس الذي يكتب فرع معالجة الأخطاء في عميله. أما أخطاء المهام غير المتزامنة، فليست أخطاء HTTP، وهي في آخر الصفحة.

شكل استجابة الخطأ

كل خطأ كائن JSON واحد، يحمل الحقول الأربعة نفسها التي تحملها الاستجابة الناجحة. قيمة success هي false، وقيمة data هي null، وstatusCode يكرر رمز HTTP، وerrorMessage هو النص المقتبس في الجداول أدناه. يحمل كل خطأ على مسار /v1 أيضًا الحقل docs، وهو رابط إلى هذه الصفحة. أما 401 فيرتبط بصفحة المصادقة بدلًا منها.

{
  "data": null,
  "statusCode": 400,
  "success": false,
  "errorMessage": "text must be shorter than or equal to 500 characters",
  "docs": "https://echonova.ai/docs/developers/errors"
}

عندما تفشل عدة قواعد تحقق في طلب واحد، تُدمج رسائلها في errorMessage واحد، مفصولة بفاصلة ومسافة. طابق الرمز أولًا، ثم الرسالة. الرسالة نص عادي وليست رمزًا، وأي تغيير فيها مذكور في سجل التغييرات.

المصادقة

يُرفض الطلب قبل تشغيل نقطة النهاية. كل 401 يحمل الرسالة نفسها، فلا يخبرك النص أي الأسباب الخمسة هو السبب. ترتيب الفحوص كاملًا في المصادقة.

الحالة errorMessage متى الإصلاح
401 Unauthorized لا يوجد header باسم Authorization، أو المخطط ليس Bearer، أو الرمز لا يبدأ بـ ek_. أرسل Authorization: Bearer ek_....
401 Unauthorized لا يطابق الرمز أي مفتاح: المفتاح مكتوب بخطأ أو غير معروف. قارن المفتاح بأول 8 أحرف منه في البوابة.
401 Unauthorized حُذف المفتاح. أنشئ مفتاحًا جديدًا.
401 Unauthorized المفتاح معطّل. فعّله من المطورون، ثم مفاتيح واجهة برمجة التطبيقات.
401 Unauthorized الحساب الذي يملك المفتاح مغلق. أرسل Authorization: Bearer ek_... بمفتاح مفعّل.
403 Subscription not found مساحة العمل التي تملك المفتاح ليس لها اشتراك. تحقّق من خطة مساحة العمل في البوابة.
403 Subscription expired or inactive الاشتراك في حالة غير النشطة والتجريبية. جدّد الاشتراك.
403 This API key does not have access to Text-to-Speech services المفتاح مقيّد، و«تحويل النص إلى كلام» ليست من خدماته. يعمل الفحص على كل مسار تحت /v1/text-to-speech، بما فيها قائمة الأصوات. تعديل المفتاح ومنحه «تحويل النص إلى كلام»، أو استخدم مفتاحًا آخر.
403 This API key does not have access to Speech-to-Text services المفتاح مقيّد، و«تحويل الكلام إلى نص» ليست من خدماته. تعديل المفتاح ومنحه «تحويل الكلام إلى نص»، أو استخدم مفتاحًا آخر.
403 This API key does not have access to Sound Cleaning services المفتاح مقيّد، و«تنقية الصوت» ليست من خدماته. تعديل المفتاح وتفعيل «تنقية الصوت»، أو استخدم مفتاحًا آخر.

حد معدل الطلبات وحد الرصيد والرصيد

يعيد خطآن مختلفان الرمز 429. اقرأ errorMessage قبل إعادة المحاولة: أحدهما يزول مع الوقت، والآخر لا يزول.

الحالة errorMessage متى الإصلاح
429 ThrottlerException: Too Many Requests أرسل المفتاح أكثر من 100 طلب إلى نقطة نهاية واحدة خلال 60 ثانية. يحمل header باسم Retry-After عدد الثواني للانتظار. يُطبَّق حد بالحجم نفسه على كل عنوان IP للعميل، للطلبات التي يرفضها فحص المفتاح فقط. ويعيد الاستجابة نفسها حتى عندما يكون المفتاح مفقودًا أو غير صالح. انتظر ثواني Retry-After، ثم أعد المحاولة. راجع حد معدل الطلبات.
429 Monthly spending limit exhausted يتجاوز الطلب حد الرصيد للمفتاح في دورة الفوترة هذه. يُرفض قبل تشغيل الطلب في كل طلب يُحتسب: نقطتا تحويل النص إلى كلام، ونقطتا تحويل الكلام إلى نص، و«تنقية الصوت». لم يُنفَّذ شيء. لا يوجد header Retry-After. ارفع الحد أو أزله من المفتاح، أو انتظر الدورة التالية. راجع الرصيد.
402 Insufficient subscription balance رصيد مساحة العمل لا يغطي تكلفة هذا الطلب. لم يُنفَّذ شيء، ولم يُحتسب أي رصيد. أضف رصيدًا إلى مساحة العمل.

التحقق من الطلب

يرفض التحقق من الجسم أو المعاملات هذه الأخطاء قبل تنفيذ أي عمل. لا يُحتسب أي رصيد. تُقصّ المسافات البيضاء في بداية كل نص ونهايته قبل فحص هذه القواعد، وتُرفض الحقول غير المعرّفة.

الحالة errorMessage متى الإصلاح
400 text must be longer than or equal to 1 characters, text should not be empty text نص فارغ أو يحتوي مسافات فقط. أرسل حرفًا واحدًا على الأقل غير مسافة.
400 text must be shorter than or equal to 500 characters, text must be longer than or equal to 1 characters, text should not be empty, text must be a string text غائب أو null. تفشل كل قواعد الحقل معًا. أرسل text كنص JSON.
400 text must be shorter than or equal to 500 characters, text must be longer than or equal to 1 characters, text must be a string text رقم أو قيمة منطقية أو كائن. أرسل text كنص JSON.
400 text must be shorter than or equal to 500 characters text تجاوز الحد في نقطتي تحويل النص إلى كلام. قسّم النص إلى عدة طلبات.
400 voiceId should not be empty, voiceId must be a string voiceId غائب أو null. أرسل id من GET /v1/text-to-speech/voices.
400 voiceId should not be empty voiceId نص فارغ. أرسل id من استدعاء الأصوات.
400 speed must not be less than 0.5 or speed must not be greater than 2 speed رقم خارج النطاق. ابقَ ضمن النطاق في أصوات تحويل النص إلى كلام وخياراته.
400 cfg must not be less than 1 or cfg must not be greater than 5 cfg رقم خارج النطاق من 1 إلى 5. أرسل cfg من 1 إلى 5.
400 speed must not be greater than 2, speed must not be less than 0.5, speed must be a number conforming to the specified constraints speed ليس رقمًا في JSON، مثل النص "1". أرسل رقمًا، لا نصًا.
400 cfg must not be greater than 5, cfg must not be less than 1, cfg must be a number conforming to the specified constraints cfg ليس رقمًا في JSON، مثل النص "1". أرسل رقمًا، لا نصًا.
400 numSteps must be one of the following values: 16, 32, 48, 64, 128 numSteps قيمة غير القيم الخمس. أرسل إحدى القيم الخمس.
400 tashkeel must be a boolean value tashkeel ليس true ولا false. أرسل قيمة منطقية في JSON.
400 property <name> should not exist يحمل الجسم أو الاستعلام حقلًا لا تعرّفه نقطة النهاية، مثل حقل من نسخة أقدم. احذف الحقل.
400 offset must not be less than 0 offset في قائمة المهام سالب. أرسل 0 أو أكثر.
400 offset must be an integer number offset ليس عددًا صحيحًا. أرسل عددًا صحيحًا.
400 limit must not be less than 1 or limit must not be greater than 100 limit في قائمة المهام خارج النطاق. أرسل من 1 إلى 100.
400 limit must not be greater than 100, limit must not be less than 1, limit must be an integer number limit ليس رقمًا أصلًا. أرسل عددًا صحيحًا من 1 إلى 100.
400 Invalid identifier voiceId ليس معرّفًا سليم التكوين، أو jobId ليس من 24 خانة سداسية عشرية. انسخ المعرّف كما أعادته الواجهة تمامًا.
400 Request body is not valid JSON لا يمكن تحليل جسم JSON، مثلًا لأن فيه فاصلة زائدة. يُرفض قبل فحص المفتاح، فلا يحصل على صف في النشاط. أرسل JSON صالحًا.
413 Request body is larger than 100 KB جسم JSON أكبر من 100 كيلوبايت. يُرفض قبل فحص المفتاح، فلا يحصل على صف في النشاط. لرفع الملفات حدها الخاص، راجع الرفع. أرسل جسمًا أصغر.
415 Content-Type must be application/json أُرسل جسم إلى POST /v1/text-to-speech أو POST /v1/text-to-speech/sync أو تذكرة ودجت بـ Content-Type غير JSON. يُفحص المفتاح أولًا، فيُسجَّل الطلب. أرسل Content-Type: application/json.

الرفع

تُطلق هذه الأخطاء على POST /v1/speech-to-text وPOST /v1/speech-to-text/sync وPOST /v1/sound-cleaning أثناء استلام الملف أو فحصه. لا يُحتسب أي رصيد. ينطبق صفوف language وnumbers_as_digits وidentify_speakers على نقطتي تحويل الكلام إلى نص فقط.

الحالة errorMessage متى الإصلاح
413 File too large الرفع أكبر من 150 ميجابايت. يُقطع الطلب قبل قراءة الملف. أعد ترميز الملف بمعدل بت أقل، أو بقناة واحدة (mono).
400 Multipart: Boundary not found يحمل header Content-Type القيمة multipart/form-data دون حدّ (boundary). يحدث هذا عندما يضبط العميل header بيده بدلًا من أن يتركه أداة الإرسال تضبطه. احذف header الذي كتبته بيدك، ودع العميل يضبطه مع الحد.
400 Unexpected file field - <name> اسم جزء الملف غير file. سمِّ الجزء file.
400 File is required لا يحتوي النموذج على جزء ملف، أو أن الطلب ليس multipart أصلًا، مثل جسم JSON أو جسم ملف خام. أرسل نموذج multipart بجزء واحد اسمه file.
400 Unsupported file type: <type>. Please upload an audio file. لا يبدأ Content-Type للجزء بـ audio/. يمثّل <type> ما أرسله عميلك، وtext/plain يعني أنه لم يرسل نوعًا. اضبط نوع الجزء، مثل audio/wav أو audio/mpeg. راجع تنسيقات تحويل الكلام إلى نص ومخرجاته.
400 Audio exceeds the 10-minute limit. مدة الملف تتجاوز الحد على نقطة تحويل الكلام إلى نص أو تنقية الصوت. قسّم التسجيل إلى أجزاء مدة كل منها 10 دقائق أو أقل.
400 Could not read the audio length. Try another file. الملف فارغ، أو تعذّر فكّ ترميزه كصوت. تحقّق من أن الملف يُشغَّل، أو صدّره مرة أخرى بصيغة شائعة.
503 Audio processing is temporarily unavailable. Please try again. عُرضت عدة ملفات للقياس في وقت واحد، أو انتهت مهلة القياس. لم يُحتسب أي رصيد. أعد المحاولة بعد انتظار قصير.
400 language must be one of: auto, ar, en يحمل حقل النموذج language قيمة غير auto أو ar أو en، مع تجاهل حالة الأحرف والمسافات حول القيمة، مثل en-US أو arabic. أرسل auto أو ar أو en، أو اترك الحقل. راجع تنسيقات تحويل الكلام إلى نص ومخرجاته.
400 numbers_as_digits must be true or false حقل النموذج numbers_as_digits ليس true أو false أو 1 أو 0. أرسل true أو false، أو اترك الحقل.
400 identify_speakers must be true or false حقل النموذج identify_speakers ليس true أو false أو 1 أو 0. أرسل true أو false، أو اترك الحقل. انظر صيغ تحويل الكلام إلى نص ومخرجاته.

تنقية الصوت

تُطلق هذه الأخطاء على POST /v1/sound-cleaning، إضافةً إلى أخطاء الرفع أعلاه.

الحالة errorMessage متى الإصلاح
400 Unsupported audio format. Sound cleaning accepts MP3, WAV, FLAC or OGG/Opus. امتداد الملف أو Content-Type ليس واحدًا من الصيغ الأربع، أو أن الاثنين لا يتطابقان. أرسل MP3 أو WAV أو FLAC أو OGG/Opus، مع امتداد ونوع متطابقين.
400 targetLufs must not be greater than -6 حقل ضبط خارج نطاقه. تسمّي الرسالة الحقل والحد. ابقَ ضمن الحد الأدنى والأقصى المذكورين للحقل.
503 Sound cleaning is temporarily unavailable. Please try again. تعذّر الوصول إلى أداة التنقية. يُسترد الرصيد المحتسب. أعد المحاولة مرة واحدة.

غير موجود

الحالة errorMessage متى الإصلاح
404 Route not found لا توجد نقطة نهاية بهذا المسار. لا تكرر الرسالة المسار. لا يُسجَّل في النشاط. قارن المسار، ومعه البادئة /v1، بصفحة نقطة النهاية.
405 Method not allowed المسار موجود، لكن ليس بهذه الطريقة. يذكر header باسم Allow الطرق التي يقبلها، مثل GET, HEAD. لا يُسجَّل في النشاط. أرسل الطلب بطريقة من Allow.
404 Voice not found لا يوجد صوت نشط بهذا voiceId. الصوت الذي سُحب يختفي من القائمة. أعد عرض الأصوات واختر واحدًا.
404 TTS Job not found معرّف المهمة غير معروف، أو أن المهمة تخص مساحة عمل أخرى، أو أنها أُنشئت من البوابة. استخدم jobId من مهام API في مساحة العمل هذه.
404 STT Job not found كالسابق، لمهام تحويل الكلام إلى نص. استخدم jobId من مهام API في مساحة العمل هذه.
404 Clean Job not found كالسابق، لمهام تنقية الصوت. استخدم jobId من مهام API في مساحة العمل هذه.

تأتي الرسائل الثلاث 404 نفسها من GET وDELETE على المهمة، وتأتي STT Job not found أيضًا من تنزيلها. يحذف المفتاح مهام API في مساحة عمله، أيًّا كان المفتاح الذي أنشأها، فالمهمة التي تخص مساحة عمل أخرى ترد 404.

حذف المهام

تُطلق هذه الأخطاء على DELETE /v1/text-to-speech/jobs/{jobId}، وDELETE /v1/speech-to-text/jobs/{jobId}، وDELETE /v1/sound-cleaning/jobs/{jobId}.

الحالة errorMessage متى الإصلاح
400 Job is still processing المهمة في حالة pending أو processing. لا تُحذف إلا مهمة مكتملة أو فاشلة. انتظر حتى تنتهي المهمة، ثم احذفها.
503 The stored file could not be deleted. Try again. تعذّرت إزالة الملف الصوتي المخزّن للمهمة. تبقى المهمة. أعد الحذف بعد انتظار قصير.

تنزيل النصوص المفرّغة

تُطلق هذه الأخطاء على GET /v1/speech-to-text/jobs/{jobId}/export، إضافةً إلى أخطاء المصادقة وحد معدل الطلبات والخدمة، وInvalid identifier، وproperty <name> should not exist، وSTT Job not found أعلاه. لا يُحتسب أي رصيد مقابل التنزيل. النجاح هو الملف نفسه، أما الخطأ فهو كائن الخطأ المعتاد.

الحالة errorMessage متى الإصلاح
400 format must be one of the following values: txt, srt, json معامل الاستعلام format مفقود، أو ليس txt أو srt أو json، مثل vtt. أرسل format=txt أو format=srt أو format=json.
400 lang must be one of the following values: en, ar معامل الاستعلام lang يحمل قيمة غير en أو ar. أرسل lang=en أو lang=ar، أو احذفه لتكون en.
400 Job is not completed المهمة في حالة pending أو processing أو failed. لا يوجد نص مفرّغ للتنزيل إلا في المهمة المكتملة. انتظر Webhook ‏job.completed، أو استعلم دوريًا عن GET /v1/speech-to-text/jobs/{jobId} حتى يصبح status هو completed.

تذاكر الودجت

تظهر عند استدعاء POST /v1/widgets/{publicId}/tickets. إصدار التذكرة مجاني. لا يُخصم أي رصيد.

الحالة errorMessage متى الإصلاح
400 ttlSeconds must not be less than 60 ttlSeconds خارج النطاق من 60 إلى 900 أو ليس عددًا صحيحًا. تسمّي الرسالة الحد. أرسل عددًا صحيحًا من الثواني بين 60 و900، أو اترك الحقل لتحصل على 300.
400 channel must be one of the following values: voice, chat channel أي قيمة أخرى. أرسل voice أو chat، أو اترك الحقل.
400 user.id must be shorter than or equal to 128 characters user.id أطول من 128 حرفًا. أرسل user.id بطول 128 حرفًا أو أقل.
400 user.id must be longer than or equal to 1 characters user.id نص فارغ. أرسل user.id غير فارغ، أو اترك الحقل.
400 user.id must not contain control characters user.id يحمل محرف تحكم مثل سطر جديد أو tab. أزل محارف التحكم من user.id.
400 user.name must be shorter than or equal to 80 characters user.name أطول من 80 حرفًا. أرسل user.name بطول 80 حرفًا أو أقل.
403 This API key does not have access to Agents المفتاح مقيّد، و«الوكلاء» ليست من خدماته. عدّل المفتاح وفعّل «الوكلاء»، أو استخدم مفتاحًا آخر.
404 widget_not_found لا يوجد ودجت بهذا publicId، أو أن الودجت يخص مساحة عمل أخرى. انسخ publicId من إعدادات الودجت لوكيل في مساحة العمل هذه.
409 widget_not_private الودجت في الوضع العام، ولا يحتاج إلى تذكرة. حوّل الودجت إلى الوضع الخاص من إعداداته.
409 widget_disabled الودجت متوقف، فلا تستطيع أي تذكرة بدء جلسة. شغّل الودجت من إعداداته.

أخطاء الخدمة

تُطلق أثناء بدء التوليد والتفريغ النصي، سواء في الاستدعاءات المتزامنة أو عند بدء الاستدعاءات غير المتزامنة. عندما لا تُقبل العملية، يُسترد الرصيد المحتسب، ويفشل الطلب بأحد هذه الأخطاء.

الحالة errorMessage متى الإصلاح
503 Speech generation is temporarily unavailable. Please try again. توليد الكلام غير متاح للطلب. عند POST /v1/text-to-speech تظهر المهمة بالحالة failed، ولا يُرسَل Webhook. أعد المحاولة بعد انتظار قصير.
503 Transcription is temporarily unavailable. Please try again. التفريغ النصي غير متاح للطلب، أو، عند POST /v1/speech-to-text/sync، تعذّر فكّ ترميز الملف. عند POST /v1/speech-to-text تظهر المهمة بالحالة failed، ولا يُرسَل Webhook. أعد المحاولة مرة واحدة. إذا فشل الملف نفسه في كل مرة، فأرسله إلى POST /v1/speech-to-text، لأن مهمته تحمل السبب في error.
400 Cloned voices work with instant generation only for now. أُرسل صوت مستنسخ إلى POST /v1/text-to-speech، وهذه النقطة لا تدعمه. استخدم POST /v1/text-to-speech/sync للأصوات المستنسخة.
400 نص حر للسبب، 300 حرف كحد أقصى رفض الطلب لسبب خاص به. نادر. اقرأ الرسالة وأصلح الطلب.
500 Something went wrong خطأ لم تصنّفه الواجهة. تحقّق من الطلب. أعد المحاولة بعد انتظار قصير، وتواصل مع الدعم إذا استمر الخطأ.
503 Database unavailable انقطاع عابر داخل الواجهة. أعد المحاولة بعد انتظار قصير.
504 Database timed out انتهاء مهلة عابر داخل الواجهة. أعد المحاولة بعد انتظار قصير.

أخفاق المهام غير المتزامنة

لا تعيد المهمة غير المتزامنة التي تفشل بعد قبولها خطأ HTTP. تصبح status للمهمة failed، ويحمل حقل error السبب، ويُسترد الرصيد، وتُرسَل في معظم الحالات Webhook باسم job.failed. ويحتفظ creditsConsumed بالمبلغ الذي حُسب.

error على المهمة متى Webhook ‏job.failed
سبب نصي عادي فشلت المهمة وأُعطي سبب. تُرسَل.
AI server generation failed فشلت مهمة تحويل النص إلى كلام دون إعطاء سبب. تُرسَل.
AI server transcription failed فشلت مهمة تحويل الكلام إلى نص دون إعطاء سبب. تُرسَل.
Job timed out — AI server did not respond بقيت المهمة في processing أكثر من 10 دقائق دون نتيجة. تتحول الحالة إلى failed خلال 15 دقيقة من POST. لا تُرسَل.
errorMessage الخاص بالرمز 503 أعلاه لم تُقبل المهمة عند الإرسال. أعاد POST نفسه الرمز 503. لا تُرسَل.

لا ترسل المهلة أي Webhook، فالعميل الذي ينتظر job.completed أو job.failed فقط لن يعرف عنها أبدًا. استخدم الاستعلام الدوري عبر GET /v1/text-to-speech/jobs/{jobId} أو GET /v1/speech-to-text/jobs/{jobId} إذا لم يصل أي حدث بعد 15 دقيقة من POST. أجسام الأحداث موجودة في أحداث Webhook.

نماذج الكود

اقرأ الحالة، ثم errorMessage. أعد المحاولة فقط عند 429 الخاص بحد معدل الطلبات، بعد ثواني Retry-After، وعند الأخطاء 503 و504. أي إعادة محاولة تُنشئ مهمة ثانية مذكورة في أعد المحاولة بأمان.

curl -s -o response.json -w "%{http_code}" \
  -X POST "https://api.echonova.ai/v1/text-to-speech/sync" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "", "voiceId": "VOICE_ID"}'
# prints 400; response.json holds "text must be longer than or equal to 1 characters, text should not be empty"

الأسئلة الشائعة

أي الأخطاء آمن لإعادة المحاولة؟

الرمز 429 الخاص بحد معدل الطلبات، بعد ثواني Retry-After، وكل 503 و504. أما 400 و401 و403 و404 و402 فتعيد الجواب نفسه حتى تغيّر الطلب أو المفتاح أو الرصيد. أي إعادة محاولة تُنشئ مهمة ثانية مذكورة في أعد المحاولة بأمان.

هل يُحتسب شيء عند ظهور خطأ؟

لا. كل خطأ مذكور أعلاه يُطلق قبل الاحتساب، أو يُسترد الرصيد قبل إعادة الخطأ.

لماذا يوجد استجابتان بالرمز 429؟

الأولى لحد معدل الطلبات، وتزول مع الوقت، وتحمل Retry-After. والثانية هي حد الرصيد للمفتاح، ولا تزول إلا عندما ترفع الحد أو تبدأ دورة الفوترة التالية، ولا تحمل أي header. فرّق بينهما من خلال errorMessage.

لماذا تقول كل استجابة 401 الشيء نفسه؟

تغطي Unauthorized header مفقودًا أو مشوّهًا، ومفتاحًا غير معروف، ومفتاحًا محذوفًا، ومفتاحًا معطّلًا، وحسابًا مغلقًا. تحقّق من header أولًا، ثم من الحالة للمفتاح تحت المطورون، ثم مفاتيح واجهة برمجة التطبيقات.

هل أطابق errorMessage في الكود؟

نعم، بعد مطابقة الرمز أولًا. الرسائل نص عادي، وأي تغيير فيها مذكور في سجل التغييرات.