操作详解
Midjourney 16 个操作的端点、字段与父任务要求
除 imagine/blend/describe/edits/video 外,以下操作都需要引用一个父任务(task_id),对父任务的状态有明确要求;父任务状态不满足要求 → 400 invalid_request_error,父任务不存在或不属于当前账户 → 404 task_not_found。全部端点鉴权与通用响应字段见接口说明。
imagine
POST /v1/midjourney/generations
POST /v1/midjourney/generations/imagine生成入口,不需要父任务。完整字段(prompt/speed/image_urls 及结构化参数)见接口说明。
blend
POST /v1/midjourney/generations/blend将 2-4 张图片混合生成一组新的四宫格候选图,不需要父任务。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
image_urls | array<string> | 是 | 2-4 张图片 URL,单图 ≤ 12 MiB;少于 2 张或多于 4 张 → 400 |
dimensions | string | 否 | 三档比例:SQUARE(1:1,默认)/PORTRAIT(2:3)/LANDSCAPE(3:2) |
size | string | 否 | 自由比例 w:h(如 "16:9");同时传时 size 覆盖 dimensions |
speed | string | 否 | relax/fast/turbo,默认 relax |
curl https://api.vibelab.me/v1/midjourney/generations/blend \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image_urls": ["https://example.com/a.png", "https://example.com/b.png"],
"speed": "fast"
}'describe
POST /v1/midjourney/generations/describe对图片做反推提示词,不需要父任务。终态响应只有 description 字段,不返回任何媒体字段。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
image_urls | array<string> | 是 | 至少 1 张图片 URL,多传只取第一张;单图 ≤ 12 MiB |
speed | string | 否 | relax/fast/turbo,默认 relax |
curl https://api.vibelab.me/v1/midjourney/generations/describe \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"image_urls": ["https://example.com/a.png"]}'上游通常 1-3 秒出结果,但仍然是异步任务——照常轮询到 SUCCESS 再取值,不要指望提交响应里就有文字。description 是四条带 1️⃣2️⃣3️⃣4️⃣ 前缀、用 \n 分隔的候选提示词,每条自带 --ar/--v 之类的参数,可以直接拿去当 imagine 的 prompt。
edits
POST /v1/midjourney/generations/edits图像编辑,不需要父任务。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
prompt | string | 是 | 编辑指令 |
image_urls | array<string> | 是 | 待编辑的图片 URL,单图 ≤ 12 MiB |
speed | string | 否 | relax/fast/turbo,默认 relax |
接口说明里那组结构化参数(size/version/stylize/raw 等)在这里同样生效。
edits 与"imagine 带垫图"的区别:edits 是改写这张图(换背景、改风格、改内容),imagine 带 image_urls 是参考这张图另画一张。要保住原图主体就用 edits。
curl https://api.vibelab.me/v1/midjourney/generations/edits \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "把背景换成雪山",
"image_urls": ["https://example.com/a.png"]
}'upscale
POST /v1/midjourney/generations/upscale对四宫格中的某一张图放大出图。父任务要求:SUCCESS。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 产出四宫格的父任务 ID |
index | integer | 语义必填 | 选中的格位,1-4;决定操作四宫格中的哪张图。平台本层不强校验该字段,遗漏或非法值由上游判定 |
custom_id | string | 否 | 取自父任务 buttons 中对应按钮的 customId;传了它就不按 index 匹配 |
curl https://api.vibelab.me/v1/midjourney/generations/upscale \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "index": 1}'结果为单张图(image_urls 一个元素,无 grid_image_url)。
普通 upscale 是从四宫格里切一张出来,不做真实放大,所以毫秒级就 SUCCESS,也几乎不会失败。真正消耗算力的是上一步的 imagine。
HD upscale(真实 2 倍放大)
如果拿到单图之后还要继续 zoom/inpaint,建议改走 HD upscale:执行真实放大,输出 2 倍高清单图,约 60-120 秒完成,后续精细操作更稳。用法是不传 index,改传对应版本的放大命令 custom_id:
customId 命令 | 适用的 imagine 版本 |
|---|---|
upsample_v5_2x / upsample_v5_4x | v5 |
upsample_v6_2x_subtle / upsample_v6_2x_creative | v6 / v6.1 |
upsample_v7_2x_subtle / upsample_v7_2x_creative | v7 |
curl https://api.vibelab.me/v1/midjourney/generations/upscale \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"custom_id": "MJ::JOB::upsample_v7_2x_subtle::1::<jobhash>"
}'HD upscale 与普通 upscale 同价。但它救不了 pan——见 pan。
variation
POST /v1/midjourney/generations/variation基于四宫格中的某一张图生成一组新的变体候选图(弱变体,等价 V1-V4)。父任务要求:SUCCESS。字段与 upscale 一致(task_id + index,可用 custom_id 覆盖)。结果为新的四宫格(grid_image_url + image_urls 四个元素)。
variation 作用在四宫格上;high_variation/low_variation 作用在 upscale 后的单图上。三者不是强度递进的同一个东西,别混用。
high_variation
POST /v1/midjourney/generations/high-variation强变化变体("Vary Strong"),改动幅度大,构图和风格都可能变。字段与 variation 一致。父任务要求:SUCCESS,且父任务通常应是 upscale 产出的单图任务。
不传 custom_id 时仍需传 index(1-4),尽管按钮匹配本身不使用它。
low_variation
POST /v1/midjourney/generations/low-variation弱变化变体("Vary Subtle"),行为与 variation 完全一致,只是独立端点、独立计费 key。字段相同,父任务要求:SUCCESS,父任务通常应是 upscale 后的单图。
新接入直接用 variation 即可,这个端点是为命名对称保留的。
reroll
POST /v1/midjourney/generations/reroll用同一 prompt 重新生成一组四宫格候选图(等价 🔄 按钮)。整格重抽,不需要 index。父任务要求:SUCCESS。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 父任务 ID |
custom_id | string | 否 | 取自父任务 buttons 中对应按钮的 customId |
只能对 imagine(或 reroll 自身产出)的四宫格 reroll。已经做过 upscale/variation/pan 的任务不能 reroll。
父任务的 prompt、版本与结构化参数都会被继承,只有种子不同——所以出图不一样但风格一致。
pan
POST /v1/midjourney/generations/pan向指定方向"接图"扩展画面:原图留在边缘,新方向补全内容。可以连续 pan 拼全景。父任务要求:SUCCESS,且必须是 upscale 产出的单图任务——直接传四宫格会被上游拒绝(This action requires an upscaled task...)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 父任务 ID(upscale 后的单图) |
direction | string | 是 | left/right/up/down;传了 custom_id 时可省 |
custom_id | string | 否 | 直接指定 pan 按钮的 customId(pan_left/pan_right/pan_up/pan_down) |
index | integer | 否 | 1-4,选父任务第几张 |
版本限制:pan 只在 v6/v6.1/v7/v8.1/v8.2/niji6 上有效,v5.2 及更早会直接 FAILURE。
另外,用 HD upscale 产出的高清单图做 pan 一样会被拒。这是 Midjourney 对 pan 本身的限制,换放大方式解决不了。
curl https://api.vibelab.me/v1/midjourney/generations/pan \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "direction": "right"}'zoom
POST /v1/midjourney/generations/zoom缩小视角(拉远扩图):原图保留,向外补背景。父任务要求:SUCCESS。
引用方式有两种,按上游当时的行为择一:
- 传
custom_id(经我们真实调用验证可用):task_id指向产出四宫格的原始imagine(或blend/zoom等同样产出四宫格的)任务,custom_id取自该任务响应buttons里的customId。 - 让上游自动匹配:
task_id指向 upscale 后的单图任务,用zoom_ratio选档,不传custom_id。
自动匹配失败时回落到第一种。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 见上方两种引用方式 |
custom_id | string | 否 | 对应按钮的 customId(Midjourney 原生字符串,如 MJ::Outpaint::...) |
zoom_ratio | number | 否 | 小于 2 匹配 Zoom Out 1.5x;未传或 >= 2 匹配 Zoom Out 2x |
index | integer | 否 | 1-4,默认 1 |
zoom 直接出图,不进 MODAL——只有 inpaint 需要两步。
curl https://api.vibelab.me/v1/midjourney/generations/zoom \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"custom_id": "MJ::Outpaint::1::<jobhash>"
}'inpaint → modal(两步流程)
局部重绘分两步提交:先 inpaint 提交重绘区域与新提示词,任务进入 MODAL 态;再调用 modal 确认继续,任务转回 IN_PROGRESS 并最终产出结果。inpaint 提交免费,真正的计费发生在 modal 步骤(见计费)。
第一步:inpaint
POST /v1/midjourney/generations/inpaint父任务要求:SUCCESS;与 zoom 一样必须引用原始产出四宫格的任务并传对应的 custom_id。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 原始产出四宫格的任务 ID |
custom_id | string | 是 | 取自父任务 buttons 中对应按钮的 customId(MJ::Inpaint::...) |
mask_url | string | 见下 | 蒙版图片 URL;透明区域 = 需要重绘的区域 |
prompt | string | 见下 | 重绘区域的新提示词 |
mask_url 和 prompt 放哪一步:我们实测走通的是在 inpaint 这步带上(上表写法)。上游文档另有一种口径,是 inpaint 只传 task_id(服务端自动匹配 Vary (Region) 按钮),把 mask_url + prompt 留到 modal 那步提交。两种都会到达上游,拿不准就先按上表来,失败了再把这两个字段挪到 modal。
蒙版要求:PNG 透明背景(也接受 data:image/png;base64,...),建议与父图同分辨率,≤ 12 MiB,URL 必须公网可达(内网地址会被 SSRF 拦截)。
curl https://api.vibelab.me/v1/midjourney/generations/inpaint \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"custom_id": "MJ::Inpaint::1::<jobhash>",
"mask_url": "https://example.com/mask.png",
"prompt": "add a hat"
}'
# => 202,任务随后进入 MODAL 态轮询 GET /v1/midjourney/{task_id},直到 status 变为 MODAL 再进行第二步。
MODAL 态有 30 分钟时限:超时未提交 modal,上游自动取消任务并退款。别把 MODAL 当成失败重试,它是等你补参的正常中间态。
第二步:modal
POST /v1/midjourney/generations/modal父任务要求:MODAL(而非 SUCCESS)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 处于 MODAL 态的父任务 ID(即上一步 inpaint 的 task_id) |
custom_id | string | 否 | 视上游需要传递 |
prompt | string | 否 | 重绘提示词;留空继承父任务 prompt。若 inpaint 那步没传,在这里补 |
mask_url | string | 否 | 蒙版 URL。有蒙版走局部重绘,没有则走外扩。若 inpaint 那步没传,在这里补 |
speed 不用在这步传:计费档位按 inpaint 提交时锁定的速度算,这步传了也不生效。
curl https://api.vibelab.me/v1/midjourney/generations/modal \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}'
# => 202,复用同一 task_id;继续轮询直到 SUCCESSmodal 提交成功后,继续用同一个 task_id 轮询即可,最终 SUCCESS 时返回新的四宫格(grid_image_url + image_urls 四个元素)。若对同一 task_id 重复提交 modal(重复计费请求)→ 409 invalid_request_error。
remix_strong
POST /v1/midjourney/generations/remix-strongv8 操作面板的"重塑":把父图重新生成一遍,可以换 prompt。强幅度,构图和风格都可能变。父任务要求:SUCCESS,且必须是 v8.1 / v8.2 的 imagine 任务——v7/v6 的父图会被拒,那些版本请改用 variation / high_variation。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 父任务 ID(v8.1/v8.2 imagine) |
index | integer | 是 | 选父图第几张做重塑,1-4 |
custom_id | string | 否 | 取自父任务 buttons 中对应按钮的 customId |
prompt | string | 否 | 重塑用的新提示词;留空继承父图 prompt |
v8 面板去掉了 U1-U4 / zoom / outpaint / inpaint。对应替代:选图变化用 variation 系列,重塑用本端点,重抽用 reroll。
remix_subtle
POST /v1/midjourney/generations/remix-subtle弱幅度重塑,保持主体与色调。字段与 remix_strong 一致,同样仅 v8.1 / v8.2 父图可用。
video
POST /v1/midjourney/generations/video图生视频,约 5 秒。必须给首帧——task_id 或 image_urls 二选一,两个都不给或都给都是 400。不支持纯文生视频。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 二选一 | 引用的父任务 ID(SUCCESS 的 imagine),用它的图作首帧 |
image_urls | array<string> | 二选一 | 直接给首帧图 URL(1 张,≤ 12 MiB) |
index | integer | 否 | 配合 task_id,选四宫格第几张作首帧(0-3) |
prompt | string | 否 | 镜头运动/动作描述;留空继承父任务 prompt |
end_url | string | 否 | 结束帧 URL。传了它,video_type 会自动升级成对应的 start_end_* |
video_type | string | 否 | 见下表,默认 vid_1.1_i2v_480 |
animate_mode | string | 否 | manual(默认)/auto;auto 必须同时给 task_id + index |
motion | string | 否 | low/high(默认 high),运动幅度,不影响计费 |
batch_size | integer | 否 | 1/2/4,默认 1;计费 = 单价 × batch_size |
video_type 只接受这四个值:
| 值 | 分辨率 | 说明 | 计费档 |
|---|---|---|---|
vid_1.1_i2v_480 | 480p | 默认 | 480p 档 |
vid_1.1_i2v_720 | 720p | 720p 档 | |
vid_1.1_i2v_start_end_480 | 480p | 起止帧(传 end_url 时自动升级) | 480p 档 |
vid_1.1_i2v_start_end_720 | 720p | 起止帧 | 720p 档 |
video 固定走 FAST 通道,没有 speed 维度——传 speed 不改变价格也不改变排队。
SUCCESS 后 video_urls 的元素个数等于 batch_size。
curl https://api.vibelab.me/v1/midjourney/generations/video \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task_id": "mj_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"index": 1,
"batch_size": 1
}'
# => 202;SUCCESS 后返回 video_urls起止帧过渡(给了 end_url,不用手动改 video_type):
curl https://api.vibelab.me/v1/midjourney/generations/video \
-H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "日出平滑过渡到日落",
"image_urls": ["https://example.com/sunrise.jpg"],
"end_url": "https://example.com/sunset.jpg",
"video_type": "vid_1.1_i2v_720"
}'