# 通用约定与任务查询
> Midjourney 走 New-API 的 `/mj/submit/*` 与 `/mj/task/*`
> 提交返回任务 ID，用查询接口取结果
> 后续动作（放大、变体、扩图）都靠任务里的 `buttons`
`POST /mj/submit/imagine`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 路径约定
提交与查询都在 `/mj` 命名空间下，动作由路径决定，没有统一的 `action` 字段：
| 动作 | 路径 |
|---|---|
| 文生图 | `POST /mj/submit/imagine` |
| 混图 | `POST /mj/submit/blend` |
| 反推提示词 | `POST /mj/submit/describe` |
| 执行按钮动作（放大、变体、扩图等） | `POST /mj/submit/action` |
| 弹窗参数（局部重绘、自定义缩放） | `POST /mj/submit/modal` |
| 图生视频 | `POST /mj/submit/video` |
| 图片编辑 / 重绘 | `POST /mj/submit/edits` |
| 材质重绘 | `POST /mj/submit/retexture` |
| 上传图片到 Discord | `POST /mj/submit/upload-discord-images` |
| 查询单个任务 | `GET /mj/task/{id}/fetch` |
| 批量查询任务 | `POST /mj/task/list-by-condition` |
| 获取任务 Seed | `GET /mj/task/{id}/image-seed` |
| 代理任务图片 | `GET /mj/image/{id}` |
路径也支持带模式前缀的写法：`POST /{mode}/mj/submit/{action}`，`{mode}` 由渠道配置决定，不确定时用不带前缀的路径。
## 提交结果
所有提交接口返回同一种信封：
```json
{
  "code": 1,
  "description": "提交成功",
  "result": "1320098173412546"
}
```
- `code` (integer) — `1` 表示成功，`22` 表示排队中，其他值为错误。
- `description` (string) — 状态描述，失败时是原因。
- `result` (string) — 任务 ID，后续查询与动作都用它。
## 任务对象
查询接口返回任务对象：
```json
{
  "id": "1320098173412546",
  "status": "SUCCESS",
  "progress": "100%",
  "imageUrl": "https://cdn.oairoute.com/mj/xxx.png",
  "imageUrls": ["https://cdn.oairoute.com/mj/xxx.png"],
  "action": "IMAGINE",
  "prompt": "a cute cat --ar 16:9",
  "promptEn": "a cute cat --ar 16:9",
  "description": "已完成",
  "failReason": "",
  "submitTime": 1763088289000,
  "startTime": 1763088291000,
  "finishTime": 1763088350000,
  "buttons": [
    { "customId": "MJ::JOB::upsample::1::UUID", "label": "U1", "emoji": "" }
  ]
}
```
- `id` (string) — 任务 ID。
- `status` (string) — 任务状态，见下表。
- `progress` (string) — 进度，带百分号的字符串。
- `imageUrl` (string) — 主图链接。
- `imageUrls` (array) — 图片链接列表，四宫格时是 4 张。
- `action` (string) — 任务类型，如 `IMAGINE`、`UPSCALE`、`VARIATION`。
- `prompt` / `promptEn` (string) — 原始提示词与规范化后的英文提示词。
- `failReason` (string) — 失败原因，仅失败时非空。
- `buttons` (array) — 可执行的动作按钮，含 `customId`、`label`、`emoji`。
- `submitTime` / `startTime` / `finishTime` (integer) — 毫秒时间戳。
## 任务状态
| 状态 | 含义 |
|---|---|
| `NOT_START` | 未开始 |
| `SUBMITTED` | 已提交，排队中 |
| `MODAL` | 等待弹窗参数，需调用 `/mj/submit/modal` 补参数 |
| `IN_PROGRESS` | 执行中 |
| `SUCCESS` | 成功 |
| `FAILURE` | 失败，看 `failReason` |
| `CANCEL` | 已取消 |
> **Note:** 
> 时间字段是**毫秒**，不是秒。这一点和其他异步任务接口不同。
## 查询参数
- `id` (string / 必填) — 路径参数，任务 ID。
- `ids` (array / 可选) — 批量查询时传任务 ID 数组。
- `notifyHook` (string / 可选) — 回调地址。任务完成时平台会向该地址 POST 结果。
- `state` (string / 可选) — 自定义透传字段，原样带回。
## 错误码
| HTTP | 含义 |
|---|---|
| 200 | 请求已受理。要看 `code` 判断是否成功，`1` 才是成功 |
| 401 | Token 缺失或无效 |
| 429 | 触发限流 |
常见失败：任务 ID 不存在；动作按钮已失效（通常因为父任务重掷过）；`customId` 与本任务不匹配。
更多状态码与重试建议见[错误码与限流](../../../support/errors.html)，常见报错的排查步骤见[常见问题](../../../support/faq.html)。
## 支持的动作
以下动作均可通过 `/mj/submit/action` 触发，`customId` 从任务的 `buttons` 里取：
| 按钮 | 效果 |
|---|---|
| `U1` 到 `U4` | 放大对应那一张 |
| `V1` 到 `U4` 变体 | 围绕那一张重新生成四宫格 |
| `Vary (Subtle)` / `Vary (Strong)` | 轻微或大幅变体 |
| `Reroll` | 重掷 |
| `Zoom Out 2x` / `Zoom Out 1.5x` | 向外扩展 |
| `Pan Left` / `Right` / `Up` / `Down` | 向指定方向平移 |
| `Vary (Region)` | 局部重绘，需要接着调 `/mj/submit/modal` |
> **Note:** 
> `buttons` 只在一段时间内有效。点击前先 fetch 一次任务，用最新的 `customId`，不要复用历史缓存。
## 使用示例
### 提交后查询
`imagine` 返回任务 ID 后，轮询 `/mj/task/{id}/fetch` 直到 `status` 为 `SUCCESS` 或 `FAILURE`。
### 批量查询
一次查多个任务，适合做列表页的状态刷新，避免逐条请求。
### 取 Seed 复现
用 `/mj/task/{id}/image-seed` 拿到 Seed，配合相同提示词与参数可以复现风格。
**提交任务{Submit}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/mj/submit/imagine' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "prompt": "a cute cat --ar 16:9",
  "botType": "MID_JOURNEY"
}'
```
**提交任务{Submit}::Python**
```
import requests

res = requests.post(
    "https://api.oairoute.com/mj/submit/imagine",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"prompt": "a cute cat --ar 16:9", "botType": "MID_JOURNEY"},
)
print(res.json())
```
**提交任务{Submit}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/mj/submit/imagine", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ prompt: "a cute cat --ar 16:9", botType: "MID_JOURNEY" }),
});
console.log(await res.json());
```
**查询任务{Fetch task}::cURL**
```
curl --request GET \
  --url 'https://api.oairoute.com/mj/task/1320098173412546/fetch' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```
**查询任务{Fetch task}::Python**
```
import requests

res = requests.get(
    "https://api.oairoute.com/mj/task/1320098173412546/fetch",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
print(res.json())
```
**查询任务{Fetch task}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/mj/task/1320098173412546/fetch", {
  headers: { Authorization: "Bearer YOUR_API_KEY" },
});
console.log(await res.json());
```
**批量查询{List by condition}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/mj/task/list-by-condition' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "ids": ["1320098173412546", "1320098173412547"]
}'
```
**批量查询{List by condition}::Python**
```
import requests

res = requests.post(
    "https://api.oairoute.com/mj/task/list-by-condition",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"ids": ["1320098173412546", "1320098173412547"]},
)
print(res.json())
```
**批量查询{List by condition}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/mj/task/list-by-condition", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ ids: ["1320098173412546", "1320098173412547"] }),
});
console.log(await res.json());
```
**200 提交任务{Submit}**
```
{
  "code": 1,
  "description": "提交成功",
  "result": "1320098173412546"
}
```
**200 查询任务{Fetch task}**
```
{
  "id": "1320098173412546",
  "status": "SUCCESS",
  "progress": "100%",
  "imageUrl": "https://cdn.oairoute.com/mj/xxx.png",
  "imageUrls": ["https://cdn.oairoute.com/mj/xxx.png"],
  "action": "IMAGINE",
  "prompt": "a cute cat --ar 16:9",
  "promptEn": "a cute cat --ar 16:9",
  "description": "已完成",
  "failReason": "",
  "submitTime": 1763088289000,
  "startTime": 1763088291000,
  "finishTime": 1763088350000,
  "buttons": [
    { "customId": "MJ::JOB::upsample::1::UUID", "label": "U1", "emoji": "" }
  ]
}
```
**200 批量查询{List by condition}**
```
[
  {
    "id": "1320098173412546",
    "status": "SUCCESS",
    "progress": "100%",
    "imageUrl": "https://cdn.oairoute.com/mj/xxx.png",
    "action": "IMAGINE",
    "prompt": "a cute cat --ar 16:9"
  }
]
```
