> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bizyair.vip/llms.txt
> Use this file to discover all available pages before exploring further.

# 调用模型

> 同步、异步、WebHook 三种调用模式，以及任务查询、取消与中断

## 调用模式总览

BizyAir 提供 3 种调用模式，通过 HTTP Header 切换，**无需修改请求体**：

| 模式      | 启用方式                                | 行为                               | 适用场景            |
| ------- | ----------------------------------- | -------------------------------- | --------------- |
| 同步阻塞    | 不设置任何特殊 Header                      | 连接保持打开直到任务完成，直接返回结果              | 短任务、简单调试        |
| 异步查询    | `X-Bizyair-Task-Async: enable`      | 立即返回 `requestId`，客户端轮询查结果        | 长任务、网络不稳定、无回调地址 |
| WebHook | `X-BizyAir-Task-WebHook-Url: <url>` | 立即返回 `requestId`，任务完成后主动 POST 回调 | 生产环境、高并发、长耗时任务  |

## 同步阻塞调用

默认模式。HTTP 连接保持打开直到任务完成。无需额外 Header。

```bash theme={null}
curl -X POST "https://api.bizyair.ai/w/v1/webapp/task/openapi/create" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "web_app_id": 38214,
    "suppress_preview_output": false,
    "input_values": {
      "84:CLIPTextEncode.text": "a futuristic cityscape at sunset",
      "88:KSampler.seed": 354884000907176,
      "81:EmptySD3LatentImage.width": 1280,
      "81:EmptySD3LatentImage.height": 1280
    }
  }'
```

响应即任务结果，包含 `outputs[].object_url`。

<Note>
  同步模式需保持长连接，请确保 HTTP 客户端的**读取超时 (Read Timeout)** 至少 60 秒，避免任务执行过程中客户端主动断开。
</Note>

## 异步查询模式

启用方式：在请求头加入 `X-Bizyair-Task-Async: enable`。

### 步骤 1：发起异步任务，立即获取 `requestId`

```bash theme={null}
curl -X POST "https://api.bizyair.ai/w/v1/webapp/task/openapi/create" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Bizyair-Task-Async: enable" \
  -d '{
    "web_app_id": 38214,
    "input_values": {
      "84:CLIPTextEncode.text": "a futuristic cityscape at sunset",
      "88:KSampler.seed": 354884000907176,
      "81:EmptySD3LatentImage.width": 1280,
      "81:EmptySD3LatentImage.height": 1280
    }
  }'
```

立即返回 `202 Accepted`：

```json theme={null}
{"requestId": "29f53793-12d3-4dd3-b2a8-4d9848e0c7da"}
```

### 步骤 2：轮询任务状态

```bash theme={null}
curl -X GET "https://api.bizyair.ai/w/v1/webapp/task/openapi/detail?requestId=29f53793-12d3-4dd3-b2a8-4d9848e0c7da" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY"
```

### 步骤 3：任务 Success 后获取结果

```bash theme={null}
curl -X GET "https://api.bizyair.ai/w/v1/webapp/task/openapi/outputs?requestId=29f53793-12d3-4dd3-b2a8-4d9848e0c7da" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY"
```

### 完整 Python 示例

```python theme={null}
import time
import requests

API_KEY = "YOUR_API_KEY"
BASE = "https://api.bizyair.ai/w/v1/webapp/task/openapi"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
    "X-Bizyair-Task-Async": "enable",
}

# 1. 提交任务
resp = requests.post(f"{BASE}/create", headers=HEADERS, json={
    "web_app_id": 38214,
    "input_values": {
        "84:CLIPTextEncode.text": "a futuristic cityscape at sunset",
        "88:KSampler.seed": 354884000907176,
        "81:EmptySD3LatentImage.width": 1280,
        "81:EmptySD3LatentImage.height": 1280,
    }
})
request_id = resp.json()["requestId"]
print(f"任务已提交: {request_id}")

# 2. 轮询状态
HEADERS.pop("X-Bizyair-Task-Async")
while True:
    r = requests.get(f"{BASE}/detail", params={"requestId": request_id}, headers=HEADERS)
    status = r.json()["data"]["status"]
    print(f"当前状态: {status}")
    if status == "Success":
        break
    elif status in ("Failed", "Canceled"):
        print("任务失败或取消"); exit(1)
    time.sleep(2)

# 3. 获取结果
r = requests.get(f"{BASE}/outputs", params={"requestId": request_id}, headers=HEADERS)
for out in r.json()["data"]["outputs"]:
    print("结果 URL:", out["object_url"])
```

## WebHook 回调模式

启用方式：在请求头加入 `X-BizyAir-Task-WebHook-Url`。

### 步骤 1：发起带 WebHook 的任务

```bash theme={null}
curl -X POST "https://api.bizyair.ai/w/v1/webapp/task/openapi/create" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-BizyAir-Task-WebHook-Url: https://your-server.com/api/callback" \
  -H "X-BizyAir-Task-Authorization: Bearer YOUR_CALLBACK_TOKEN" \
  -d '{
    "web_app_id": 35661,
    "input_values": {
      "1:EmptyLatentImage.width": "1024",
      "1:EmptyLatentImage.height": "1024",
      "2:BizyAir_BasicScheduler.steps": "20",
      "3:BizyAir_RandomNoise.noise_seed": "1",
      "4:BizyAirSiliconCloudLLMAPI.user_prompt": "小猫，梵高风格",
      "4:BizyAirSiliconCloudLLMAPI.system_prompt": "你是一个 stable diffusion prompt 专家..."
    }
  }'
```

立即返回 `202 Accepted` + `requestId`。

### 步骤 2：在回调端接收结果

任务完成后 BizyAir 会向你指定的 URL 发起 POST 请求：

* **Method**: `POST`
* **Headers**: `Content-Type: application/json`、`User-Agent: Go-http-client/1.1`、以及你设置的 `X-BizyAir-Task-Authorization` 和其他 `X-Bizyair-Task-*` Header
* **Body**: 包含完整任务结果

### 回调端 Node.js 示例

```javascript theme={null}
const express = require("express");
const app = express();
app.use(express.json());

const EXPECTED_TOKEN = process.env.CALLBACK_TOKEN;

app.post("/api/callback", (req, res) => {
  const auth = req.get("Authorization");
  if (EXPECTED_TOKEN) {
    const ok = auth?.startsWith("Bearer ") && auth.split(" ")[1] === EXPECTED_TOKEN;
    if (!ok) return res.status(401).json({ message: "invalid token" });
  }

  const payload = req.body;
  console.log("Received callback for request_id:", payload.request_id);

  res.status(200).json({ ok: true });
});

app.listen(3000, () => console.log("Callback server on :3000"));
```

<Warning>
  回调端**必须返回 HTTP 200 OK**。若返回非 200、超时或无响应，平台会按策略重试（约每 6 秒一次，最多 10 次）。单次回调超时时间约 10 秒。
</Warning>

## 如何选择调用模式

| 你的场景              | 推荐模式           | 理由               |
| ----------------- | -------------- | ---------------- |
| 本地脚本快速验证          | 同步阻塞           | 最简单，一次请求直接拿结果    |
| 短任务集成到后端          | 同步阻塞           | 短任务 HTTP 连接开销可接受 |
| 视频生成 / 3D 渲染（长任务） | WebHook        | 不阻塞服务、可大规模并行     |
| 客户端网络不稳定          | 异步查询           | 不依赖长连接，可按需轮询     |
| 批量并行百上个任务         | 异步查询 或 WebHook | 全部排队后慢慢回收        |
| 生产环境高可用           | WebHook        | 主动推送 + 重试机制      |

## 查询任务状态

获取任务的当前状态与详细元数据（排队信息、运行时长等）。

```bash theme={null}
curl -X GET "https://api.bizyair.ai/w/v1/webapp/task/openapi/detail?requestId={requestId}" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY"
```

**响应字段**（`data` 内）：

| 字段                    | 类型             | 说明               |
| --------------------- | -------------- | ---------------- |
| `type`                | string         | 任务类型，如 `"API"`   |
| `status`              | string         | 任务状态枚举           |
| `created_at`          | string         | 创建时间（UTC+8）      |
| `updated_at`          | string         | 最后更新时间           |
| `executed_at`         | string         | 开始执行时间           |
| `ended_at`            | string \| null | 结束时间，未结束为 `null` |
| `expired_at`          | string         | 结果文件过期时间         |
| `inference_cost_time` | integer        | 推理耗时（秒）          |
| `queue_info`          | object \| null | 仅 `Queuing` 时出现  |

**状态枚举**：

| 状态值         | 含义              | 建议操作                        |
| ----------- | --------------- | --------------------------- |
| `Queuing`   | 排队中，等待资源调度      | 继续轮询，间隔 1-3 秒               |
| `Preparing` | 准备中，正在加载模型 / 环境 | 继续轮询                        |
| `Running`   | 运行中             | 继续轮询                        |
| `Success`   | 成功              | **停止轮询**，获取结果               |
| `Failed`    | 失败              | **停止轮询**，检查 `error_message` |
| `Canceled`  | 已取消             | **停止轮询**                    |

## 查询任务结果

获取**已完成任务**的产出物（`object_url` 等）。

```bash theme={null}
curl -X GET "https://api.bizyair.ai/w/v1/webapp/task/openapi/outputs?requestId={requestId}" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY"
```

**响应示例**：

```json theme={null}
{
  "code": 20000,
  "message": "Ok",
  "status": true,
  "data": {
    "request_id": "29f53793-12d3-4dd3-b2a8-4d9848e0c7da",
    "status": "Success",
    "outputs": [
      {
        "object_url": "https://storage.bizyair.ai/outputs/xxx.png",
        "output_ext": ".png",
        "cost_time": 10657,
        "audit_status": 2,
        "error_type": "NOT_ERROR"
      }
    ]
  }
}
```

**`outputs[].` 字段说明**：

| 字段             | 类型      | 说明                                       |
| -------------- | ------- | ---------------------------------------- |
| `object_url`   | string  | 结果文件下载 URL                               |
| `output_ext`   | string  | 文件扩展名（含 `.`）                             |
| `cost_time`    | integer | 从任务开始到产出此结果的耗时（毫秒）                       |
| `audit_status` | integer | 审核状态：`1` 未审核 / `2` 通过 / `3` 不通过 / `4` 报错 |
| `error_type`   | string  | 失败时为具体错误码，成功为 `"NOT_ERROR"`              |
| `error_msg`    | string  | 失败时的详细原因（可选）                             |

## 取消任务

仅对**排队中**（`Queuing`）的任务生效，将其从队列移除。

```bash theme={null}
curl -X PUT "https://api.bizyair.ai/w/v1/webapp/task/openapi/cancel?requestId={requestId}" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json"
```

<Note>
  取消操作是幂等的，重复调用不会产生副作用。若任务已进入运行态，请改用中断任务。
</Note>

## 中断任务

仅对**运行中**（`Running`）的任务生效，强制停止。

```bash theme={null}
curl -X PUT "https://api.bizyair.ai/w/v1/webapp/task/openapi/interrupt?requestId={requestId}" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json"
```

<Warning>
  中断运行中的任务，**已执行部分仍会产生费用**。仅当任务处于 `Queuing` 时取消才不计费。
</Warning>
