# 任務與有限等待

讀取任務狀態、點數和輸出，也可不經輪詢等待任務完成。

來源：https://scifig.ai/zh-Hant/docs/api/jobs

## 讀取任務

`GET /jobs/{id}`（權限範圍 `figures:read`）回傳與建立請求相同的任務物件。其他帳戶的任務和未知 ID 均回傳 `404 NOT_FOUND`。`GET /jobs?limit=10&cursor=…` 按最新優先列出你的任務（每頁 1–20 個，使用 `next_cursor` 繼續讀取）。

```json
{
  "id": "5f4a9a5e-fc45-4eae-9f9c-56b5f686cba5",
  "kind": "chart",
  "status": "succeeded",
  "created_at": "2026-10-14T11:20:05.000Z",
  "credits": { "reserved": 50, "charged": 50, "refunded": 0 },
  "outputs": [
    {
      "file_id": "0b7c…",
      "format": "png",
      "width": 2126,
      "height": 1417,
      "download_url": "https://scifig.ai/api/v1/files/0b7c…?exp=…&sig=…",
      "expires_at": "2026-10-14T12:21:40.000Z",
      "editor_url": "https://scifig.ai/app/datachart?conversation=…"
    }
  ],
  "error": null
}
```

`kind` 為 `image_generation`、`image_edit`、`image_upscale`、`image_conversion`、`chart` 或 `flowchart`。響應不包含你的提示詞、輸入或內部標識。

| 輸出欄位 | 出現條件 | 含義 |
| --- | --- | --- |
| file_id | always | 傳給其他端點或 `GET /files/{file_id}` |
| format | always | 輸出的副檔名，例如 `png`、`svg` 或 `pdf` |
| width, height | PNG 輸出 | 畫素尺寸 |
| download_url, expires_at | always | 簽名連結，有效期一小時 |
| editor_url | 圖表和流程圖任務 | 在網站工作臺中開啟結果；插圖和轉換結果沒有此欄位 |

## 狀態生命週期

| status | 含義 |
| --- | --- |
| queued | 已接納，等待可用容量 |
| processing | 執行中 |
| succeeded | 已完成；`outputs` 已就緒並已扣除點數 |
| failed | 未產生結果；`error.code` 說明原因，預留點數已返還 |
| canceled | 完成前已停止；點數已返還 |

| 失敗任務的 `error.code` | 含義 | 處理方式 |
| --- | --- | --- |
| TASK_TIMED_OUT | 任務超時，點數已返還。插圖產生或編輯可能攜帶 `late_delivery_until`：在此時間之前，結果仍可能免費交付。 | 繼續讀取任務直到 `late_delivery_until`；否則請用新金鑰傳送新請求 |
| CONTENT_REJECTED | 任務執行期間，內容政策拒絕了結果，點數已返還。在建立時請求本身被拒絕，則以 `422` 回傳相同代碼。 | 修改提示詞或輸入，並使用新金鑰 |
| ADMISSION_INCOMPLETE | 可重試錯誤阻止任務啟動，未消耗點數。 | 使用相同 Idempotency-Key 傳送相同請求 |
| TASK_NOT_FOUND | 任務已被接納，但已找不到對應的執行任務。 | 使用新金鑰傳送新請求 |
| TASK_FAILED | 任務失敗，點數已返還。沒有獨立公開代碼的引擎錯誤統一為 `TASK_FAILED`；引擎代碼位於 `details.reason`。 | 使用新金鑰傳送新請求 |
| INTERNAL_ERROR | 任務失敗但未報告原因，點數已返還。 | 使用新金鑰傳送新請求 |

`succeeded`、`failed` 和 `canceled` 為終態，但有一個例外：因 `TASK_TIMED_OUT` 失敗的插圖產生或編輯任務攜帶 `late_delivery_until`。在此時間之前，結果仍可能免費交付，任務轉為 `succeeded`；請繼續讀取任務，不要新建任務。

列表中任一任務無法讀取時，`GET /jobs` 回傳 `503 SERVICE_UNAVAILABLE` 和 `Retry-After: 3`；請重試列表請求，不會將該任務替換為失敗結果。

## 有限等待

- 建立請求中的 `Prefer: wait=N`（1–30）會保持響應等待，直到任務終結或經過 N 秒。終態任務回傳 `200`；仍在執行的任務回傳 `202`，帶有 `Location: /api/v1/jobs/{id}` 和 `Retry-After`。
- 等待不會改變任務：`202` 不是錯誤，響應回傳後任務繼續執行。
- 輪詢 `GET /jobs/{id}` 的間隔不得短於 `Retry-After`（3 秒）。插圖通常在 20–90 秒完成，圖表和流程圖通常在 30–120 秒完成。
- 失敗任務也可能記錄被拒絕的請求：建立請求被 `402 INSUFFICIENT_CREDITS` 或 `422 CONTENT_REJECTED` 等錯誤拒絕後，會作為帶有對應代碼、未扣點數的 `failed` 任務保留在 `GET /jobs` 中。
- 伺服器整合應在等待前儲存任務 ID，避免連線中斷導致再次建立任務。

## cURL

```bash
curl https://scifig.ai/api/v1/jobs/<job_id> \
  -H "Authorization: Bearer $SCIFIG_API_KEY"
```

## JavaScript

```javascript
const response = await fetch('https://scifig.ai/api/v1/jobs/<job_id>', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.SCIFIG_API_KEY}`,
  },
});
const result = await response.json();
console.log(response.status, result);
```

## Python

```python
import os

import requests

headers = {
    "Authorization": f"Bearer {os.environ['SCIFIG_API_KEY']}",
}
response = requests.get(
    "https://scifig.ai/api/v1/jobs/<job_id>",
    headers=headers,
    timeout=60,
)
print(response.status_code, response.json())
```
