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

المطورون

الاستدعاءات المتزامنة وغير المتزامنة

أي أسلوب استدعاء يناسب الطلب، وكيف تمر المهمة بحالاتها الأربع، وكيف تستعلم عن النتيجة دوريًا.

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

الأسلوبان

متزامن غير متزامن
تحويل النص إلى كلام POST /v1/text-to-speech/sync POST /v1/text-to-speech
تحويل الكلام إلى نص POST /v1/speech-to-text/sync POST /v1/speech-to-text
ما يعيده jobId وstatus، مع النتيجة: audioUrl أو transcription، مع durationSeconds وcreditsConsumed. jobId وstatus فقط.
الاتصال مفتوح حتى تصبح النتيجة جاهزة. يُغلق بمجرد قبول المهمة.
status في الاستجابة completed processing
مكان النتيجة في الاستجابة. في GET .../jobs/{jobId}، أو في Webhook من نوع job.completed.
أحداث المهمة لا شيء. لا يُرسل الاستدعاء المتزامن أي حدث Webhook أبدًا. job.completed أو job.failed.
tashkeel مُطبَّق. مقبول، والنص يُركَّب كما هو مكتوب. استخدم نقطة النهاية المتزامنة للتشكيل.

جسم الطلب واحد في نقطتي تحويل النص إلى كلام، ورفع multipart/form-data واحد في نقطتي تحويل الكلام إلى نص. تسرد صفحات المرجع كل حقل: توليد الكلام بشكل متزامن، وتوليد الكلام من النص، وتفريغ الصوت بشكل متزامن، وتفريغ ملف صوتي.

ما يشتركان فيه

  • الخصم يأتي أولًا. يسعّر الـ API الطلب، ويخصم من مساحة العمل، ثم ينفّذ العمل. إذا لم يغطِّ الرصيد التكلفة، يُرفض الاستدعاء بالرمز 402 والرسالة Insufficient subscription balance قبل أن يُشغَّل أي شيء. انظر الرصيد.
  • كل استدعاء ينشئ مهمة. ينشئ الاستدعاء المتزامن المهمة وهي completed بالفعل، وينشئ الاستدعاء غير المتزامن المهمة وهي pending. تظهر كلتاهما في GET /v1/text-to-speech/jobs أو GET /v1/speech-to-text/jobs، الأحدث أولًا، ويمكن قراءتهما من GET .../jobs/{jobId}. يستطيع أي مفتاح في مساحة العمل له وصول إلى ذلك المنتج قراءة المهمة.
  • الفشل يُسترد. حين يفشل استدعاء متزامن، تحصل على استجابة خطأ ويُسترد الخصم. وحين تفشل مهمة غير متزامنة، تصبح حالتها failed، ويحمل error السبب، ويُسترد الخصم.
  • الغلاف نفسه. كل استجابة هي { "success", "statusCode", "errorMessage", "data" }، وكل استدعاء ناجح، بما فيه POST، يعيد الرمز HTTP 200. انظر نظرة عامة على Developer API.

اختيار الأسلوب

استخدم نقطة النهاية المتزامنة حين تتحقق كل هذه الشروط:

  • تحتاج إلى النتيجة داخل الطلب نفسه، مثلًا للرد على رسالة في محادثة، أو لتشغيل عبارة أثناء مكالمة.
  • المدخل ضمن الحد: صوت مدته 10 دقائق أو أقل لتحويل الكلام إلى نص، و500 حرف لتحويل النص إلى كلام. تشترك نقطتا كل خدمة في الحد، فحجم المدخل لا يفرض الاختيار أبدًا.
  • يستطيع عميلك إبقاء اتصال HTTP مفتوحًا طوال مدة العمل. لا تضع الـ API مهلة خاصة به على الاستدعاء المتزامن، لذا اضبط مهلة عميلك مع أخذ حجم المدخل في الحسبان.

استخدم نقطة النهاية غير المتزامنة في كل الحالات الأخرى:

  • الدفعات. أرسل مهام كثيرة، ثم استعلم عنها دوريًا، أو دع Webhook يخبرك بانتهاء كل واحدة.
  • العملاء ذوو مهلة HTTP قصيرة، أو الأعمال التي لا تريد أن تحجزها.
  • أي حالة تريد فيها أن يُسلَّم حدث job.completed أو job.failed إلى نقطة نهايتك، بدلًا من إبقاء الاتصال مفتوحًا.

يكلّف الأسلوبان الرصيد نفسه للمدخل نفسه. الاختيار يتعلق بكيفية استلامك النتيجة، لا بالسعر.

اربط الأسلوب بمن ينتظر. الشخص الذي ينتظر ردًا يريد رحلة ذهاب وإياب واحدة، والدفعة تريد اتصالًا غير محجوز وWebhook.

الموصى به

  • رد في محادثة: POST /v1/text-to-speech/sync، والنتيجة في الاستجابة.
  • خمسمئة تسجيل ليلًا: POST /v1/speech-to-text لكل تسجيل، مع Webhook على job.completed وjob.failed.

الأقل فاعلية

  • رد في محادثة: POST /v1/text-to-speech، ثم حلقة استعلام تُبقي المستخدم منتظرًا المدة نفسها مضافًا إليها فاصل الاستعلام.
  • خمسمئة تسجيل ليلًا: POST /v1/speech-to-text/sync بالتوازي، مع مهلة عميل 30 دقيقة على كل اتصال.

دورة حياة المهمة

للمهمة أربع حالات: pending وprocessing وcompleted وfailed. تمر المهمة غير المتزامنة بها بهذا الترتيب:

POST accepted
     |
     v
  pending  -->  processing  -->  completed
                    |
                    +--------->  failed
الحالة ماذا تعني ما يحمله كائن المهمة
pending خُصم الرصيد وأُنشئت المهمة، وهي تنتظر القبول للمعالجة. لا يعود POST إلا بعد أن تغادر المهمة هذه الحالة، لذلك لا يمكنك رؤيتها إلا في قائمة مهام تُجلب أثناء بقاء POST قيد التنفيذ. لا توجد حقول نتيجة.
processing تجري معالجة المهمة. تحويل النص إلى كلام: لا audioUrl ولا durationSeconds. تحويل الكلام إلى نص: يحمل durationSeconds تقديرًا مأخوذًا من الملف، والحقل transcription غائب.
completed النتيجة جاهزة. تحويل النص إلى كلام: audioUrl وdurationSeconds. تحويل الكلام إلى نص: transcription وdurationSeconds كما قيست.
failed فشلت المهمة، أو انتهت مهلتها. يُسترد الرصيد. error ويحمل السبب. يبقى creditsConsumed يُظهر المبلغ الذي خُصم ثم أُعيد.

ثلاث قواعد تسري على كل مهمة:

  • تنتهي المهمة مرة واحدة. لا تنتقل المهمة من completed إلى failed، ولا تُكمَل مرتين.
  • لا تبقى المهمة في processing إلى الأبد. المهمة التي بقيت processing لأكثر من 10 دقائق تُعلَّم failed مع error بالقيمة Job timed out — AI server did not respond، ويتغير الحالة خلال 15 دقيقة من POST. يُسترد الرصيد. هذه المهلة لا ترسل حدث job.failed عبر Webhook، لذلك فحلقة الاستعلام، أو استعلام احتياطي بعد 15 دقيقة من الصمت، هما الطريقة لمعرفة ذلك.
  • الرفض عند الإرسال يُبلَّغ عنه مرتين. إذا رفضت الخدمة المهمة وقت إرسالها عبر POST، تُعلَّم المهمة failed، ويُسترد الرصيد، ويعيد POST نفسه خطأً، غالبًا 503 مع Speech generation is temporarily unavailable. Please try again. أو Transcription is temporarily unavailable. Please try again.. تبقى المهمة الفاشلة في قائمة مهامك.

للاستدعاء المتزامن قصة أقصر: تظهر المهمة completed حين تصبح النتيجة جاهزة، وإذا فشل الاستدعاء فلا تُنشأ أي مهمة. تحصل على استجابة الخطأ والاسترداد.

الاستعلام عن المهمة

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

curl https://api.echonova.ai/v1/text-to-speech/jobs/JOB_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

كائن المهمة يسمي معرّفه id، بينما أعاد POST الذي بدأها jobId. الحقول:

الحقل مهمة تحويل النص إلى كلام مهمة تحويل الكلام إلى نص
id دائمًا دائمًا
status دائمًا دائمًا
createdAt دائمًا دائمًا
creditsConsumed دائمًا دائمًا
text دائمًا غير موجود
voiceId دائمًا غير موجود
durationSeconds عند completed دائمًا؛ تقدير حتى completed
audioUrl عند completed غير موجود
transcription غير موجود عند completed
error عند failed عند failed
language غير موجود دائمًا
numbersAsDigits غير موجود دائمًا

audioUrl رابط موقّع إلى ملف WAV، وله مدة صلاحية تنتهي. كل GET للمهمة يعيد رابطًا جديدًا، فاستعلم مرة أخرى بدلًا من تخزين الرابط. انزل الملف بطلب GET عادي دون ترويسة Authorization.

أمران يجب تذكرهما أثناء الاستعلام:

  • كل استعلام يُحتسب من حد المعدل، وهو 100 طلب كل 60 ثانية لكل مفتاح على تلك النقطة. انتظر بضع ثوانٍ بين الاستعلامات. انظر حدود معدل الطلبات.
  • ضع للحلقة موعدًا نهائيًا. تصل كل مهمة إلى completed أو failed خلال 15 دقيقة من دخولها processing.

النمط الكامل، مع التراجع التدريجي عند 429 و5xx، موجود في إعادة المحاولة بأمان.

Webhook بدلًا من الاستعلام

حين تنتهي مهمة غير متزامنة، يرسل الـ API الحدث job.completed أو job.failed إلى كل Webhook مفعّل في مساحة العمل يشترك في ذلك الحدث. يحمل job.completed النتيجة نفسها: audioUrl لتحويل النص إلى كلام، وtranscription لتحويل الكلام إلى نص، فلا تحتاج إلى استدعاء نقطة نهاية المهمة بعد ذلك. ويحمل job.failed القيمة error. لا يرسل الاستدعاء المتزامن أيًا من الحدثين، ولا تُرسل مهلة الـ 10 دقائق أيضًا. انظر إعداد Webhook وأحداث Webhook.

الحدود

الحد القيمة ينطبق على
طول text من 1 إلى 500 حرف POST /v1/text-to-speech وPOST /v1/text-to-speech/sync
مدة الصوت 10 دقائق POST /v1/speech-to-text/sync وPOST /v1/speech-to-text
حجم الملف 150 ميجابايت نقطتا رفع تحويل الكلام إلى نص
الوقت في processing 10 دقائق، ثم تُعلَّم failed خلال 15 دقيقة من POST المهام غير المتزامنة
الطلبات 100 كل 60 ثانية لكل مفتاح ولكل نقطة نهاية كل نقطة نهاية، بما فيها الاستعلامات

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

هل تقبل نقطة النهاية غير المتزامنة مدخلًا أطول؟

لا. تقبل نقطتا تحويل النص إلى كلام حتى 500 حرف، وتقبل نقطتا تحويل الكلام إلى نص حتى 10 دقائق من الصوت.

هل يمكنني الحصول على تشكيل في مهمة غير متزامنة؟

لا. يُطبَّق tashkeel على POST /v1/text-to-speech/sync فقط. تقبل نقطة النهاية غير المتزامنة الحقل، وتركّب النص كما هو مكتوب.

هل يظهر الاستدعاء المتزامن في قائمة مهامي؟

نعم، وهو completed بالفعل، بالقيمة نفسها لـ creditsConsumed وaudioUrl أو transcription الموجودة في الاستجابة.

لماذا انتهت مهمتي بحالة failed دون Webhook؟

انتهت مهلتها بعد أكثر من 10 دقائق في processing، ولا ترسل المهلة أي حدث. استعلم عن المهمة حين تمر 15 دقيقة دون أن تصل نتيجة.

هل تبقى النتيجة محفوظة بعد انتهاء المهمة؟

نعم. يعيد GET .../jobs/{jobId} النص المفرّغ، أو audioUrl جديدًا، حتى تحذف المهمة عبر DELETE .../jobs/{jobId} أو تُغلق حسابك. يستطيع أي مفتاح في مساحة العمل له وصول إلى ذلك المنتج حذف مهامه. ومهمة من مساحة عمل أخرى تعيد 404.