# المصادقة

يحتاج كل استدعاء يشغّل نموذجًا أو يقرأ طلباتك إلى مفتاح API. الكتالوج (`GET /models`،
`GET /categories`) و`POST /quote` ووثيقة OpenAPI عامة.

## مفاتيح API

أنشئ المفاتيح وألغِها من [https://doitong.com/developers/dashboard#keys](https://doitong.com/developers/dashboard#keys). يبدو المفتاح
مثل `doitong_` متبوعًا بـ 64 حرفًا سداسيًا عشريًا، ويُعرض مرة واحدة فقط عند إنشائه. أرسله في ترويسة
`Authorization`:

```bash
curl https://api.doitong.com/v1/account -H "Authorization: Bearer $DOITONG_API_KEY"
```

يعمل `X-API-Key: <key>` أيضًا.

> [!WARNING]
> احتفظ بالمفاتيح على خادمك: يمكن لأي شخص يملك مفتاحًا إنفاق أرصدة API المسموح له بإنفاقها. إذا تسرّب مفتاح،
> فألغِه وأنشئ مفتاحًا جديدًا.

يحصل الطلب الذي لا يتضمن مفتاحًا على `401` مع الرمز `missing_api_key`؛ كما يحصل المفتاح المجهول أو المُلغى أو المنتهي
على `401` أيضًا.

## النطاقات

يحمل كل مفتاح نطاقات. تتحقق API الخاصة بالنماذج من النطاقات التالية:

| الإجراء | النطاق المطلوب |
|---|---|
| تشغيل نموذج، إلغاء طلب، حذف ملفات طلب، تغيير إعداد التخزين | `models:run` (تعمل أيضًا المفاتيح ذات `images:create` أو `videos:create` الأقدم) |
| إنشاء عنوان URL للرفع | `models:run` أو `media:upload` |
| قراءة الطلبات والحساب | `models:read` (يقرأ المفتاح الذي يمكنه تشغيل النماذج أيضًا) |

تحصل المفاتيح الجديدة على `models:read` و`models:run` افتراضيًا. يحصل الاستدعاء الذي لا يتضمن النطاق الصحيح على
`403` مع الرمز `insufficient_scope`.

## ميزانيات الأرصدة

يمكن أن يحمل المفتاح ميزانيته الخاصة بأرصدة API (1,000 رصيد API = ⁨‏1 $⁩)، التي يحددها مالك الحساب: ميزانية إجمالية أو
ميزانية يومية (آخر 24 ساعة) أو كلتاهما. قبل احتساب رسوم العملية، تُقارن التكلفة بما أنفقه المفتاح بالفعل من خلال
هذه API (بعد خصم عمليات الاسترداد). يُرفض التشغيل الذي سيتجاوز الميزانية مع `402 budget_exceeded` ولا تُحتسب
أي رسوم.

> [!IMPORTANT]
> رفض الميزانية نهائي: لن تساعد إعادة المحاولة حتى يرفع المالك الميزانية.

 يمكن لمفتاح بلا ميزانية إنفاق ما يصل إلى رصيد API. وبشكل منفصل، يحصل التشغيل الذي لا يغطيه رصيد API على `402 insufficient_credits`
مع `top_up_url`.

يعرض `GET https://api.doitong.com/v1/account` رصيد API والميزانية المتبقية للمفتاح (وكلاهما بأرصدة API):

```json 200 OK · account
{
  "object": "account",
  "credits": 125000,
  "balance": { "credits": 125000, "usd": "125.00" },
  "top_up_url": "https://doitong.com/developers/dashboard#balance",
  "key": {
    "name": "Production server",
    "prefix": "doitong_3fa9c1e...",
    "scopes": ["models:read", "models:run"],
    "budget_remaining": 50000,
    "rate_limit": 3600,
    "rate_limit_remaining": 3571
  },
  "webhook_signing_secret": "whsec_..."
}
```

تكون قيمة `budget_remaining` هي `null` عندما لا تكون للمفتاح ميزانية خاصة به.

## حدود المعدل

يمكن لكل مفتاح إجراء 3600 طلب في الساعة ما لم يُضبط حده على خلاف ذلك. تحمل كل استجابة موثّقة الحالة الحالية:

| الترويسة | المعنى |
|---|---|
| `X-RateLimit-Limit` | عدد الطلبات المسموح بها في النافذة الحالية |
| `X-RateLimit-Remaining` | الطلبات المتبقية في النافذة الحالية |
| `X-RateLimit-Reset` | وقت Unix لإعادة ضبط النافذة |

عند تجاوز الحد، تحصل على `429` مع ترويسة `Retry-After` (بالثواني). يُحتسب الاستطلاع الطويل باستخدام `?wait=` طلبًا واحدًا
لكل استدعاء، لذا يكون الانتظار أوفر من الاستطلاع السريع.

يوجد أيضًا حد يبلغ 10 طلبات قيد التنفيذ (`queued` أو `running`) لكل حساب. يؤدي بدء طلب إضافي إلى إرجاع
`429 too_many_inflight`؛ ابدأه مرة أخرى بعد انتهاء أحد الطلبات.
