# 任务与有限等待

读取任务状态、积分和输出，也可不经轮询等待任务完成。

来源：https://scifig.ai/zh/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())
```
