الطلبات
الطلب هو استدعاء واحد لنموذج واحد. وله معرّف (req_…) وحالة وتكلفة بأرصدة API (1000 = 1 USD)، وعند نجاحه، الملفات المُنشأة. يعيد كل نقطة نهاية أدناه الكائن نفسه لكل نموذج.
العثور على نموذج
كتالوج النماذج الـ1,496 الكامل هو JSON عام (لا حاجة إلى مفتاح):
curl "https://api.doitong.com/v1/models?category=text-to-video&lab=Google&limit=20"
| معلمة الاستعلام | المعنى |
|---|---|
q |
كلمات يجب أن تظهر جميعها في الاسم أو المعرّف أو الجهة المطوّرة أو الوسوم، مثل kling 3. |
category |
معرّف فئة واحد، مثل text-to-video أو upscale. يعرض GET https://api.doitong.com/v1/categories جميع الفئات الـ21 مع أعدادها. |
lab |
الجهة المطوّرة للنموذج، بالاسم أو المعرّف، مثل Google أو black-forest-labs. |
family |
معرّف family من صف سابق: كل متغيرات نموذج واحد (pro، fast، image-to-video، …). |
mode |
exact (تُحسب التكلفة من المدخل)، أو measured (من طول ملفات المدخل أو حجمها)، أو estimate (سعر تقديري لكل تشغيل)، أو metered (تُفرض التكلفة حسب الاستخدام الفعلي، حتى حد أقصى لكل تشغيل). |
limit, cursor |
حجم الصفحة (من 1 إلى 100، الافتراضي 50) وnext_cursor للصفحة السابقة. |
يحتوي كل صف على id وname وlab وcategory وfamily وsummary وtags وoutput_kind وdocs_url وكائن price (راجع التسعير). يضيف GET https://api.doitong.com/v1/models/{model_id} مخطط JSON الكامل للمدخل والمخرج، وأسماء المعلمات الأساسية، وقواعد التسعير، ومدخلًا نموذجيًا. تؤدي category أو mode غير المعروفة إلى 400 invalid_parameter.
تشغيل نموذج
curl -X POST "https://api.doitong.com/v1/run/{model_id}?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1842-cover" \
-d '{"prompt": "..."}'
- الجسم هو مدخل النموذج، وهو كائن JSON. تسرد صفحة كل نموذج معلماته.
- يُتحقق من المدخل قبل فرض أي تكلفة. يعيد المدخل غير الصالح
422 invalid_inputمعparamالمخالف، ولا يكلّف شيئًا. - يعلّق
?wait=N(حتى 20 ثانية) الاستدعاء حتى ينتهي الطلب أو ينقضي الوقت. - يرسل
?webhook_url=https://…طلب POST موقّعًا إلى ذلك العنوان عند انتهاء الطلب (راجع Webhooks). - يحدد
?storage=permanentأو?storage=temporaryمدة الاحتفاظ بملفات المخرج؛ وبدونه يُطبّق إعداد الحساب (راجع مكان حفظ الملفات).
تكون الاستجابة 202 Accepted ما دام الطلب قيد التنفيذ، و200 OK عند انتهائه ضمن مدة الانتظار (أو عندما يكون إعادة تشغيل، راجع أدناه). تحمل ترويساتا Location وDoitong-Request-Id عنوان الطلب ومعرّفه.
الحالات
-
queuedتم القبول وخصم التكلفة، وبانتظار عامل -
runningالنموذج قيد التوليد -
الحالات النهائية:
succeededتم خصم تكلفة العرض؛ تحتوي outputs[] على عناوين URL في مساحة التخزين لديناfailedتم رد التكلفة تلقائيًا؛ يوضح الخطأ السببcanceledتم الإيقاف قبل ظهور نتيجة؛ وتم رد التكلفة
| الحالة | المعنى | نهائية |
|---|---|---|
queued |
قُبل وفُرضت تكلفته، وينتظر عاملًا. قد يعرض queue_position موضعه في الصف. |
لا |
running |
النموذج يُنشئ المخرج. | لا |
succeeded |
اكتمل. تسرد outputs الملفات. |
نعم |
failed |
أوقفه النموذج أو أحد الحدود. يوضح error السبب. تُسترد أرصدة API. |
نعم |
canceled |
أُلغي قبل إنتاج نتيجة. تُسترد أرصدة API. | نعم |
يفشل الطلب الذي يتجاوز حده الزمني بالرمز timeout وتُسترد تكلفته: 15 دقيقة للصور، و60 دقيقة للفيديو، و30 دقيقة للصوت وكل ما عدا ذلك.
كائن الطلب
{
"id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
"object": "request",
"model": "flux/schnell",
"status": "succeeded",
"created_at": "2026-10-20T12:00:00Z",
"started_at": "2026-10-20T12:00:01Z",
"completed_at": "2026-10-20T12:00:02Z",
"queue_position": null,
"cost": { "credits": 3, "usd": "0.003", "charged": 3, "refunded": 0 },
"input": { "prompt": "..." },
"output": { "images": [ { "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "width": 1024, "height": 768 } ] },
"outputs": [
{ "type": "image", "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "content_type": "image/jpeg",
"width": 1024, "height": 768, "file_size": 183920, "stored": true }
],
"error": null,
"metrics": { "inference_seconds": 1.2 },
"storage": { "mode": "permanent", "bytes": 183920, "expires_at": null, "expired": false },
"urls": {
"self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
"cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
}
}
- تكون
outputsمتطابقة لكل نموذج: إدخال واحد لكل ملف مُنشأ معtype(imageأوvideoأوaudioأوfileأو3d)، وurlعلى تخزيننا، وcontent_type، وعند معرفتها،file_sizeوwidthوheightوduration. - تكون
outputكائن النتيجة الخاص بالنموذج (تُسرد حقوله في صفحة كل نموذج) مع عناوين URL نفسها. - توضّح
storageكيفية حفظ الملفات:mode(permanentأوtemporary)، وbytesالمخزنة، وexpires_at(وقت حذف الملف المؤقت، وnullللملفات الدائمة)، وexpired(trueبعد زوال الملفات). - تمثل
cost.creditsسعر الاستدعاء بأرصدة API (cost.usdبوحدة USD)، وتمثلcost.chargedما خُصم من رصيد API، وتمثلcost.refundedما أُعيد. في نموذجmetered، تمثلcost.creditsالحد الأقصى المحتجز في البداية (cost.held)؛ وبعد نجاح التشغيل، توضحcost.settledقيمة الاستخدام، ويكون باقي الحد الأقصى فيcost.refunded(راجع الفوترة حسب الاستخدام). - عند فشل الطلب، تكون
errorهي{ "type": …, "code": …, "message": … }.
قراءة طلب
curl "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
-H "Authorization: Bearer $DOITONG_API_KEY"
- تنفذ
?wait=N(حتى 20 ثانية) استطلاعًا طويلًا: يعيد الاستدعاء النتيجة فور وصول الطلب إلى حالة نهائية، أو بعد N ثانية مع الحالة الحالية. ويُعد تكرار ذلك أبسط طريقة لانتظار النتيجة. - تضيف
?logs=1أسطر سجل تقدم النموذج (آخر 50 سطرًا) باسمlogs.
يمكنك قراءة طلبات حسابك فقط؛ وأي معرّف آخر يعيد 404 request_not_found.
سرد الطلبات
curl "https://api.doitong.com/v1/requests?limit=20&status=succeeded&model=flux/schnell" \
-H "Authorization: Bearer $DOITONG_API_KEY"
من الأحدث إلى الأقدم. تتراوح limit من 1 إلى 100 (الافتراضي 20)، وتقوم status وmodel بالتصفية. تكون الاستجابة { "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }؛ مرّر cursor=<next_cursor> للصفحة التالية.
إلغاء طلب
curl -X POST "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
-H "Authorization: Bearer $DOITONG_API_KEY"
- إذا أُلغي قبل بدء النموذج: تصبح الحالة
canceled، وتُسترد أرصدة API، وتحصل على200. - إذا كان النموذج يُنشئ المخرج بالفعل: يُمرر الإلغاء وتحصل على
202مع"cancel_requested": true. وإذا انتهى النموذج رغم ذلك، ينجح الطلب بصورة طبيعية وتُفرض تكلفته. - إذا كان الطلب نهائيًا بالفعل:
409 not_cancelable(أما الطلب الذي حالتهcanceledفيعيد200ببساطة).
حذف ملفات طلب
curl -X DELETE "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/files" \
-H "Authorization: Bearer $DOITONG_API_KEY"
يحذف نسخنا من ملفات مخرج الطلب فورًا ويوقف رسوم تخزينها. تكون الاستجابة كائن الطلب مع storage.expired: true؛ وتبقى عناوين URL الخاصة به في السجل لكنها لا تعود تعمل. لا يغيّر استدعاؤه مرة أخرى شيئًا (200). لا يملك الطلب الذي لا يزال queued أو running ملفات بعد: 409 request_active. يتطلب models:run.
قابلية التكرار: إعادة المحاولة دون الدفع مرتين
قد تفشل الشبكات. لإعادة محاولة تشغيل بأمان، أرسل ترويسة Idempotency-Key (أي سلسلة تصل إلى 255 حرفًا، وفريدة لكل عملية، مثل معرّف طلبك الخاص):
- المفتاح نفسه والجسم نفسه كما سبق: تحصل على الطلب الأصلي مجددًا (
200، والترويسةIdempotent-Replayed: true)، ولا تُفرض أي تكلفة مرة أخرى. - المفتاح نفسه والجسم نفسه بعد تشغيل فشل قبل وصوله إلى النموذج (
upstream_errorأوinternal_errorعند الإرسال، أوinsufficient_creditsأوbudget_exceededأوtoo_many_inflight): لم يُنتج شيء ولم تُفرض تكلفة، لذا تعيد المحاولة تشغيل النموذج بدلًا من إعادة الفشل. - المفتاح نفسه مع جسم مختلف:
409 idempotency_mismatch. - ترتبط المفاتيح بمفتاح API الذي أرسلها.
مكان حفظ الملفات
يُنسخ كل ملف مخرج إلى تخزيننا قبل وضع علامة succeeded على الطلب، لذلك تكون عناوين URL في outputs على مضيفاتنا ويمكنك الربط بها مباشرة. وتختار أنت مدة بقائها:
| الوضع | المدة | السعر |
|---|---|---|
permanent (افتراضي) |
حتى تحذفها | 100 أرصدة API (0.10 $) لكل GB شهريًا، تُفرض يوميًا من رصيد API |
temporary |
7 يومًا، ثم تُحذف | مجانًا |
- يحدد إعداد الحساب ما يحدث للطلبات الجديدة: مفتاح التبديل "الاحتفاظ بالملفات إلى الأبد" في لوحة التحكم، أو
PATCH https://api.doitong.com/v1/account/storageمع{"mode": "temporary"}. يعرضGET https://api.doitong.com/v1/accountالإعداد ضمنstorage، مع وحدات البايت التي تحتفظ بها والتقدير الشهري. - يتجاوز
?storage=permanent|temporaryفي التشغيل (وسيطةstorageلأداة MCPrun) الإعداد لذلك التشغيل. - لا يلمس تغيير الإعداد الملفات الموجودة لديك؛ احذفها باستخدام
DELETE /requests/{id}/files. - عندما يتعذر على رصيد API دفع تكلفة التخزين، لا تُفرض أي تكلفة وتتلقى بريدًا إلكترونيًا: اشحن الرصيد خلال 30 يومًا، وإلا تصبح الملفات المحتفظ بها مؤقتة وتُحذف بعد 7 يومًا.
في الحالة النادرة التي تفشل فيها عملية النسخ لدينا، يحتوي الإدخال على "stored": false ويكون عنوان URL هو الأصلي قصير الصلاحية: نزّله قريبًا.