# خطاها

هر نقطه پایانی به یک شکل خطا می‌دهد: یک وضعیت HTTP و یک پوشش JSON.

```json
{
  "error": {
    "type": "invalid_request",
    "code": "invalid_input",
    "message": "duration must be one of 5, 10.",
    "param": "duration",
    "details": [ { "param": "duration", "message": "duration must be one of 5, 10." } ],
    "request_id": null,
    "doc_url": "https://doitong.com/developers/docs/errors#invalid_input"
  }
}
```

| فیلد | معنا |
|---|---|
| `type` | دستهٔ کلی خطا. بر اساس آن تصمیم بگیرید چه کاری انجام دهید. |
| `code` | دلیل دقیق، ثابت و قابل‌خواندن برای ماشین. هر کد بخش مخصوصی در ادامه دارد؛ `doc_url` به آن لینک می‌دهد. |
| `message` | توضیح قابل‌فهم برای انسان که ثبت یا نمایش آن به توسعه‌دهنده بی‌خطر است. |
| `param` | پارامتر ورودی یا سرصفحهٔ مشکل‌دار، در صورت وجود. |
| `details` | برای خطاهای ورودی، همهٔ مشکلات پیدا‌شده: `[{ "param", "message" }]`. |
| `request_id` | درخواستی که خطا به آن مربوط است، در صورت وجود. |

برای فراخوانی‌ای که با خطا برمی‌گردد، هزینه‌ای دریافت نمی‌شود. درخواستی که *پس از* پذیرفته‌شدن شکست بخورد، وضعیت
`failed` را حفظ می‌کند، در شیء درخواست دارای `error: { "type", "code", "message" }` است و به‌طور خودکار بازپرداخت می‌شود.

## انواع

| نوع | وضعیت HTTP | اقدام |
|---|---|---|
| `invalid_request` | 400، 413 یا 422 | درخواست را اصلاح کنید. تلاش دوباره با همان فراخوانی مجدداً شکست می‌خورد. |
| `authentication_error` | 401 | کلید معتبری را در `Authorization: Bearer <key>` ارسال کنید. |
| `permission_error` | 403 | از کلیدی با scope لازم استفاده کنید. |
| `not_found` | 404 | شناسهٔ مدل یا شناسهٔ درخواست را بررسی کنید. |
| `insufficient_credits` | 402 | موجودی API را افزایش دهید (`top_up_url` در خطا). |
| `budget_exceeded` | 402 | بودجهٔ خود کلید تمام شده است. نهایی: از مالک کلید بخواهید آن را افزایش دهد. |
| `conflict` | 409 | منبع در وضعیتی نیست که این فراخوانی را مجاز کند. |
| `rate_limited` | 429 | `Retry-After` ثانیه صبر کنید، سپس دوباره تلاش کنید. |
| `upstream_error` | 502 | backend مدل شکست خورده است. تلاش مجدد با همان `Idempotency-Key` بی‌خطر است: دوباره اجرا می‌شود؛ هزینه‌ای از شما دریافت نشده است. |
| `service_unavailable` | 503 | API متوقف است یا یکی از وابستگی‌ها از دسترس خارج شده است. بعداً دوباره تلاش کنید. |
| `internal_error` | 500 | اشکال از سمت ماست. دوباره تلاش کنید؛ اگر ادامه داشت، زمان و `request_id` را برای پشتیبانی ارسال کنید. |

## کدها

### `invalid_request`

درخواست ناقص یا نامعتبر عمومی (400).

### `invalid_json`

بدنه JSON معتبر نیست (400).

### `invalid_body`

بدنه JSON معتبر است، اما شیء نیست؛ ورودی مدل باید یک شیء JSON باشد (400).

### `body_too_large`

بدنه بزرگ‌تر از 16 MB است (413). فایل‌های بزرگ را بارگذاری کنید و به‌جای آن URL آن‌ها را ارسال کنید (به [فایل‌ها](https://doitong.com/developers/docs/files) مراجعه کنید).

### `invalid_parameter`

یک پارامتر query مقدار نادرستی دارد؛ برای مثال `limit` خارج از بازهٔ 1 تا 100 است، `wait` عدد نیست، `status` یا
`category` ناشناخته است، یا `storage` مقداری به‌جز `permanent` / `temporary` دارد (400). `param` نام آن را مشخص می‌کند.

### `invalid_category`

`GET /openapi.json?category=` دسته‌ای را مشخص می‌کند که وجود ندارد (400). `GET https://api.doitong.com/v1/categories` آن‌ها را فهرست می‌کند.

### `invalid_cursor`

`cursor` یک فراخوانی فهرست به این فهرست تعلق ندارد (400). بدون cursor از ابتدا شروع کنید.

### `invalid_idempotency_key`

سرصفحهٔ `Idempotency-Key` خالی است یا بیش از 255 نویسه دارد (400).

### `invalid_arguments`

فراخوانی ابزار MCP آرگومان ناقص یا نادرستی دارد (فقط MCP). `param` نام آرگومان را مشخص می‌کند.

### `invalid_input`

ورودی مدل اعتبارسنجی را پشت سر نمی‌گذارد (422): پارامتر ناشناخته (پیام نزدیک‌ترین نام معتبر را پیشنهاد می‌کند)،
پارامتر الزامیِ مفقود، نوع نادرست، مقدار خارج از فهرست یا بازهٔ مجاز، یا ارائهٔ هم‌زمان نام canonical و
native با مقادیر متفاوت. `param` نخستین پارامتر مشکل‌دار است و `details` همهٔ آن‌ها را فهرست می‌کند.
هزینه‌ای دریافت نمی‌شود.

### `unsupported_file`

یک فایل دارای نوعی است که نمی‌پذیریم (422)؛ برای مثال بارگذاری با پسوند پشتیبانی‌نشده، یا `content_type`
که با پسوند مطابقت ندارد.

### `invalid_webhook_url`

`webhook_url` یک URL عمومی `https://` نیست (422). آدرس‌های خصوصی، محلی و سادهٔ `http://` رد می‌شوند.

### `missing_api_key`

نقطه پایانی به کلید API نیاز دارد، اما کلیدی ارسال نشده است (401).

### `invalid_api_key`

کلید ناشناخته، لغوشده یا منقضی‌شده است (401).

### `insufficient_scope`

کلید scope موردنیاز این فراخوانی را ندارد (403)؛ برای مثال `models:run` برای اجرا، یا `models:read` برای خواندن
درخواست‌ها و موجودی. به [احراز هویت](https://doitong.com/developers/docs/authentication#scopes) مراجعه کنید.

### `account_disabled`

حساب بسته یا تعلیق شده است (403). کلیدهای آن دیگر کار نمی‌کنند.

### `not_found`

مسیر وجود ندارد (404).

### `model_not_found`

هیچ مدل عمومی‌ای با این شناسه وجود ندارد (404). مدل‌ها را با `GET https://api.doitong.com/v1/models` فهرست کنید.

### `request_not_found`

هیچ درخواستی با این شناسه در حساب شما وجود ندارد (404). درخواست‌های حساب‌های دیگر هرگز قابل مشاهده نیستند.

### `insufficient_credits`

**موجودی API** حساب (اعتبار API، ۱٬۰۰۰ اعتبار API = ⁨‎$۱⁩ — نه اعتبار برنامه‌های Doitong) هزینهٔ این فراخوانی را پوشش نمی‌دهد
(402). پاسخ پیش از دریافت هرگونه هزینه ارسال می‌شود. خطا شامل `top_up_url` است؛ در [https://doitong.com/developers/dashboard#balance](https://doitong.com/developers/dashboard#balance) موجودی را افزایش دهید
و دوباره تلاش کنید.

```json
{ "error": { "type": "insufficient_credits", "code": "insufficient_credits",
             "message": "This request costs 560 API credits ($0.56); the API balance is 120 API credits ($0.12). Top up at https://doitong.com/developers/dashboard#balance",
             "top_up_url": "https://doitong.com/developers/dashboard#balance", "doc_url": "https://doitong.com/developers/docs/errors#insufficient_credits" } }
```

### `budget_exceeded`

این فراخوانی از بودجهٔ خود کلید API برحسب اعتبار API فراتر می‌رود (402). بودجه را مالک کلید تعیین می‌کند؛ تلاش مجدد تا زمانی که او آن را افزایش ندهد، کمکی نمی‌کند.

### `conflict`

فراخوانی با وضعیت فعلی منبع تعارض دارد (409).

### `idempotency_mismatch`

`Idempotency-Key` قبلاً با بدنه‌ای متفاوت استفاده شده است (409). برای عملیات جدید از کلید جدیدی استفاده کنید.

### `idempotency_in_progress`

درخواستی با همین `Idempotency-Key` اکنون در حال ایجاد است (409). لحظه‌ای بعد دوباره تلاش کنید تا آن را دریافت کنید.

### `request_active`

درخواست همچنان `queued` یا `running` است، بنابراین هنوز فایلی برای حذف ندارد (409). پس از پایان آن فایل‌ها را حذف کنید.

### `not_cancelable`

درخواست از قبل `succeeded` یا `failed` است و نمی‌توان آن را لغو کرد (409).

### `rate_limited`

کلید در بازهٔ فعلی درخواست‌های بیش از حدی ارسال کرده است (429). سرصفحه‌های `X-RateLimit-*` و `Retry-After` را ببینید.

### `too_many_inflight`

حساب از قبل 10 درخواست `queued` یا `running` دارد (429). درخواست بعدی را وقتی یکی از آن‌ها تمام شد آغاز کنید.

### `upstream_error`

backend مدل درخواست را رد کرده یا در پردازش آن شکست خورده است (502 هنگام اجرا، یا `failed` با این کد در درخواست). اعتبار API
بازپرداخت می‌شود. اگر خود backend ورودی را رد کرده باشد، فراخوانی به‌جای آن `422 invalid_input` را با پیام مربوطه برمی‌گرداند.

### `upstream_lost`

backend مدل دیگر درخواست را نمی‌شناسد، بنابراین هیچ نتیجه‌ای دریافت نخواهد شد. وضعیت آن به `failed` با این کد
(نوع `upstream_error`) پایان می‌یابد و بازپرداخت می‌شود. آن را دوباره اجرا کنید.

### `timeout`

درخواست بیش از محدودیت خود اجرا شده است (15 دقیقه برای تصویر، 60 برای ویدیو، 30 در سایر موارد) و متوقف شده است. وضعیت آن به
`failed` با این کد پایان می‌یابد و بازپرداخت می‌شود.

### `service_unavailable`

API موقتاً متوقف است یا یکی از وابستگی‌ها، مانند بارگذاری فایل، از دسترس خارج شده است (503). بعداً دوباره تلاش کنید.

### `internal_error`

مشکلی از سمت ما رخ داده است (500). دوباره تلاش کنید؛ اگر ادامه داشت، با پشتیبانی تماس بگیرید.

### `charge_failed`

به‌دلیل مشکلی داخلی، امکان دریافت هزینه از حساب وجود نداشت (500). وضعیت درخواست `failed` می‌شود؛ هیچ مبلغی
برداشت نشده است. دوباره تلاش کنید.

### `pricing_unavailable`

قیمت مدل پیکربندی نشده است، بنابراین در حال حاضر امکان اعلام قیمت یا اجرای آن وجود ندارد (500).
