# בקשות

בקשה היא קריאה אחת למודל אחד. יש לה מזהה (`req_…`), סטטוס, עלות בקרדיטי API (1000 = 1 USD), וכאשר היא
מסתיימת בהצלחה — את הקבצים שנוצרו. אותו אובייקט מוחזר מכל נקודת קצה למטה, עבור כל מודל.

## מציאת מודל

הקטלוג של כל 1,496 המודלים הוא JSON ציבורי (אין צורך במפתח):

```bash
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` (ראו [תמחור](https://doitong.com/developers/docs/pricing#price-objects)). `GET https://api.doitong.com/v1/models/{model_id}` מוסיף את
סכימת ה-JSON המלאה של הקלט והפלט, את שמות הפרמטרים הקנוניים, את כללי המחיר ודוגמה לקלט. `category` או `mode` לא מוכרים
מחזירים `400 invalid_parameter`.

## הרצת מודל

```bash
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 חתום לכתובת הזו כשהבקשה מסתיימת (ראו [webhook](https://doitong.com/developers/docs/webhooks)).
- `?storage=permanent` או `?storage=temporary` בוחר כמה זמן קובצי הפלט יישמרו; בלעדיו חלה הגדרת החשבון
  (ראו [היכן הקבצים נשמרים](#storage)).

התגובה היא `202 Accepted` כל עוד הבקשה עדיין בעבודה, ו-`200 OK` כשהיא הסתיימה במהלך זמן ההמתנה (או כאשר זו הפעלה חוזרת,
ראו להלן). הכותרות `Location` ו-`Doitong-Request-Id` מכילות את כתובת הבקשה ואת המזהה שלה.

## סטטוסים

מחזור החיים של בקשה: `queued` → `running` → `succeeded` | `failed` | `canceled` (סופי; בקשות שנכשלו או בוטלו מזוכות).

| סטטוס | משמעות | סופי |
|---|---|---|
| `queued` | התקבלה וחויבה, וממתינה לעובד. `queue_position` עשוי להציג את מיקומה בתור. | לא |
| `running` | המודל מייצר. | לא |
| `succeeded` | הסתיימה בהצלחה. `outputs` מציג את הקבצים. | כן |
| `failed` | המודל או מגבלה עצרו אותה. `error` מסביר מדוע. קרדיטי ה-API מוחזרים. | כן |
| `canceled` | בוטלה לפני שהפיקה תוצאה. קרדיטי ה-API מוחזרים. | כן |

בקשה שנמשכת מעבר למגבלת הזמן שלה נכשלת עם הקוד `timeout`, והחיוב מוחזר: 15 דקות לתמונות,
60 דקות לווידאו, 30 דקות לאודיו ולכל השאר.

## אובייקט הבקשה

```json
{
  "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`
  (ראו [חיוב לפי שימוש](https://doitong.com/developers/docs/pricing#metered)).
- כאשר בקשה נכשלת, `error` הוא `{ "type": …, "code": …, "message": … }`.

## קריאת בקשה

```bash
curl "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

- `?wait=N` (עד 20 שניות) מבצע long-polling: הקריאה חוזרת מיד כשהבקשה סופית, או לאחר N שניות עם המצב הנוכחי.
  לולאה על פרמטר זה היא הדרך הפשוטה ביותר להמתין לתוצאה.
- `?logs=1` מוסיף את שורות יומן ההתקדמות של המודל (50 האחרונות) בתור `logs`.

אפשר לקרוא רק בקשות של החשבון שלך; כל מזהה אחר מחזיר `404 request_not_found`.

## הצגת בקשות

```bash
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>` כדי לקבל את העמוד הבא.

## ביטול בקשה

```bash
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`).

## מחיקת קובצי בקשה

```bash
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 ימים, ואז נמחקים | ללא עלות |

- הגדרת החשבון קובעת עבור בקשות חדשות: המתג "שמירת קבצים לצמיתות" ב-[לוח הבקרה](https://doitong.com/developers/dashboard#balance),
  או `PATCH https://api.doitong.com/v1/account/storage` עם `{"mode": "temporary"}`. `GET https://api.doitong.com/v1/account` מציג אותה תחת
  `storage`, עם מספר הבתים שנשמרים וההערכה החודשית.
- `?storage=permanent|temporary` בהרצה (הארגומנט `storage` של כלי `run` ב-MCP) עוקף אותה עבור ההרצה הזו.
- שינוי ההגדרה לעולם אינו משפיע על קבצים שכבר ברשותך; מחק אותם באמצעות
  [`DELETE /requests/{id}/files`](#delete-files).
- כאשר יתרת ה-API אינה יכולה לשלם על האחסון, לא מתבצע חיוב ונשלחת אליך הודעת דוא״ל: טען את היתרה בתוך
  30 ימים, אחרת הקבצים הנשמרים יהפכו לזמניים ויימחקו 7 ימים לאחר מכן.

במקרה הנדיר שבו העותק שלנו נכשל, הרשומה כוללת `"stored": false` וה-URL הוא המקורי וקצר-הטווח:
הורד אותו בהקדם.
