Midjourney API 怎么调用?2026 完整接入教程,3 种方案实测

作者:互联网

2026-03-20

其他

上周接了个私活,甲方要做 AI 壁纸生成小程序,核心就是调 Midjourney 出图。我寻思这不简单嘛,结果一上手才发现——Midjourney 官方压根没有公开的 REST API。Discord Bot 那套交互逻辑,要自己模拟消息发送、轮询图片结果,中间还得处理排队、超时、CDN 图片链接过期这些问题。折腾了差不多两天,踩了一圈坑,总算把三种方案都跑通了,这篇写完整流程。

直接回答标题问题:Midjourney 官方没有公开 REST API,2026 年主流接入方式有三种——自建 Discord Bot 中转、使用第三方 Midjourney API 代理服务、通过 AI 聚合 API 平台一站式调用。 三种方案各有优劣,下面挨个讲代码和踩坑。

先说结论

方案接入难度稳定性延迟成本适合场景
自建 Discord Bot⭐⭐⭐⭐ 高一般,容易被风控取决于 Discord只付 MJ 订阅费个人玩具/研究
第三方 MJ API 代理⭐⭐ 中看服务商中等按次计费偏贵中小项目快速上线
聚合 API 平台⭐ 低多通道冗余较高较低按量付费生产环境/多模型混用

环境准备

不管选哪种方案,你都需要:

  • Python 3.10+(示例用 Python,Node.js 逻辑一样)
  • 一个 Midjourney 付费订阅账号(Basic Plan 起步,$10/月)
  • pip install openai requests aiohttp

方案一:自建 Discord Bot 中转

最原始的方案。原理是:你的代码通过 Discord Bot 向 Midjourney Bot 发送 /imagine 命令,然后轮询频道消息拿到生成的图片。

sequenceDiagram
 participant App as 你的应用
 participant Bot as Discord Bot
 participant MJ as Midjourney Bot
 participant CDN as Discord CDN
 
 App->>Bot: 发送绘图 prompt
 Bot->>MJ: /imagine prompt
 MJ-->>Bot: 排队处理中...
 MJ-->>Bot: 图片生成完成
 Bot->>App: 返回图片消息
 App->>CDN: 下载图片

核心代码(简化版):

import requests
import time

DISCORD_BOT_TOKEN = "your-bot-token"
CHANNEL_ID = "your-channel-id"
MJ_BOT_ID = "936929561302675456" # Midjourney Bot 的固定 ID

HEADERS = {
 "Authorization": f"Bot {DISCORD_BOT_TOKEN}",
 "Content-Type": "application/json"
}

def send_imagine(prompt: str):
 """通过 Discord 交互命令发送 /imagine"""
 payload = {
 "type": 2,
 "application_id": MJ_BOT_ID,
 "channel_id": CHANNEL_ID,
 "data": {
 "name": "imagine",
 "options": [{"name": "prompt", "type": 3, "value": prompt}]
 }
 }
 resp = requests.post(
 "https://discord.com/api/v10/interactions",
 json=payload,
 headers=HEADERS
 )
 print(f"发送状态: {resp.status_code}")
 return resp.status_code == 204

def poll_result(timeout=120):
 """轮询频道消息,等待 MJ 出图"""
 start = time.time()
 while time.time() - start < timeout:
 resp = requests.get(
 f"https://discord.com/api/v10/channels/{CHANNEL_ID}/messages?limit=5",
 headers=HEADERS
 )
 messages = resp.json()
 for msg in messages:
 if msg.get("author", {}).get("id") == MJ_BOT_ID:
 attachments = msg.get("attachments", [])
 if attachments and "png" in attachments[0].get("url", ""):
 return attachments[0]["url"]
 time.sleep(5)
 return None

# 使用
send_imagine("a cyberpunk cat sitting on a neon rooftop --ar 16:9 --v 6")
image_url = poll_result()
print(f"图片地址: {image_url}")

这套方案的坑,真的多

  1. Discord 交互命令鉴权变了:2026 年 Discord 把 Interaction 端点的鉴权收紧了,Bot Token 直接调 /interactions 会 403,得用 User Token 模拟——但这违反 Discord ToS,号随时可能被封
  2. 轮询逻辑不靠谱:MJ 生成过程中会发多条消息(进度 25%、50%、100%),你得判断哪条是最终结果,光靠「有没有 png 附件」不够,还得检查消息内容里有没有 (fast)(relaxed) 标记
  3. CDN 链接会过期:Discord 的图片 CDN 链接带签名参数,大概 24 小时后失效,生产环境必须下载到自己的 OSS

跑通 demo 之后我就放弃了。个人玩玩可以,上生产等着被 Discord 风控吧。

方案二:第三方 Midjourney API 代理

市面上有不少服务商把方案一的脏活包装成了标准 REST API,比如 midjourney-proxy、go-midjourney 这些开源项目,也有商业化服务。

接口一般长这样:

import requests
import time

API_BASE = "https://your-mj-proxy.com" # 替换成你用的代理服务地址
API_KEY = "your-api-key"

def imagine(prompt: str):
 resp = requests.post(
 f"{API_BASE}/mj/submit/imagine",
 json={"prompt": prompt},
 headers={"Authorization": f"Bearer {API_KEY}"}
 )
 task = resp.json()
 task_id = task["result"]
 print(f"任务已提交, task_id: {task_id}")
 
 # 轮询任务状态
 for _ in range(60):
 status_resp = requests.get(
 f"{API_BASE}/mj/task/{task_id}/fetch",
 headers={"Authorization": f"Bearer {API_KEY}"}
 )
 data = status_resp.json()
 if data["status"] == "SUCCESS":
 return data["imageUrl"]
 elif data["status"] == "FAILURE":
 raise Exception(f"生成失败: {data.get('failReason')}")
 time.sleep(3)
 
 raise TimeoutError("等了 3 分钟还没出图,超时了")

url = imagine("a watercolor painting of Tokyo street in rain --ar 3:2 --v 6")
print(url)

比方案一省心,不用自己维护 Discord Bot,但问题也明显:

  • 代理服务稳定性参差不齐,我测了三家,有一家高峰期排队能排 5 分钟
  • 价格不透明,按张收费 ¥0.5-2/张,也有包月的
  • 依赖别人的 Discord 账号池,对方被封你也跟着挂

方案三:通过聚合 API 平台调用

这是我最后在生产环境用的方案。ofox.ai 是一个 AI 模型聚合平台,一个 API Key 可以调用 GPT-5、Claude Opus 4.6、Gemini 3 Pro、Midjourney 等 50+ 模型,低延迟直连无需代理,支持支付宝付款。它把 Midjourney 封装成了兼容 OpenAI 协议的接口,改个 base_url 就能用。对我来说最大的好处是——文生图和文生文用同一套代码逻辑,一个 Key 搞定。

from openai import OpenAI
import requests

client = OpenAI(
 api_key="your-ofox-key",
 base_url="https://api.ofox.ai/v1" # 聚合接口,一个 Key 调 MJ/GPT/Claude
)

# 调用 Midjourney 生图
response = client.images.generate(
 model="midjourney",
 prompt="a cyberpunk cat sitting on a neon rooftop, cinematic lighting --ar 16:9 --v 6",
 n=1,
 size="1024x1024"
)

image_url = response.data[0].url
print(f"图片地址: {image_url}")

# 同一个 client 直接调文本模型,不用换 Key
chat = client.chat.completions.create(
 model="gpt-5",
 messages=[{"role": "user", "content": "给这张赛博朋克猫的壁纸起 5 个文案"}]
)
print(chat.choices[0].message.content)
graph LR
 A[你的代码] -->|OpenAI 兼容协议| B[ofox.ai 聚合网关]
 B --> C[Midjourney]
 B --> D[DALL·E 3]
 B --> E[GPT-5]
 B --> F[Claude Opus 4.6]
 B --> G[Gemini 3 Pro]
 
 style B fill:#f9f,stroke:#333,stroke-width:2px

这套方案跑了两周,实际体感:

  • 出图速度大概 30-90 秒,跟直接用 MJ 差不多
  • 不用操心 Discord 账号池和风控
  • 文生图 + 文生文统一一套 SDK,代码量少了一半

踩坑记录

坑 1:Midjourney 参数放在 prompt 里还是参数里?

一开始我以为 --ar 16:9 这种参数要单独传,结果发现不管哪种方案,MJ 的参数都是直接拼在 prompt 字符串尾部的。别去找什么 aspect_ratio 字段,没有的。

坑 2:图片尺寸参数 size 会被忽略

用 OpenAI 兼容接口调 MJ 时,size="1024x1024" 不生效,实际尺寸由 prompt 里的 --ar 决定。我一开始不知道,图出来全是正方形,debug 了半天才反应过来没加 --ar

坑 3:prompt 里别带中文

MJ 对中文 prompt 的理解一直很迷,经常出离谱的结果。我的做法是先让 GPT-5 把中文需求翻译成英文 prompt,再喂给 MJ:

def translate_prompt(chinese_desc: str) -> str:
 resp = client.chat.completions.create(
 model="gpt-5",
 messages=[
 {"role": "system", "content": "你是 Midjourney prompt 专家。将用户的中文描述翻译为高质量英文 MJ prompt,直接输出 prompt,不要解释。"},
 {"role": "user", "content": chinese_desc}
 ]
 )
 return resp.choices[0].message.content.strip()

en_prompt = translate_prompt("一只橘猫坐在日式庭院里看樱花,水彩风格")
print(en_prompt)
# 输出类似: an orange tabby cat sitting in a Japanese garden watching cherry blossoms, watercolor style, soft pastel colors, Studio Ghibli inspired --ar 3:2 --v 6

坑 4:回调比轮询靠谱

方案二和方案三很多服务支持 webhook 回调。别用轮询,生产环境轮询既浪费请求次数又不及时。设置回调 URL,图生成完直接推给你。

小结

2026 年调 Midjourney API,说白了就三条路:自己搞 Discord Bot(折腾但便宜)、用第三方代理(省事但看运气)、用聚合平台(最省心,要付服务费)。

我选了方案三,因为这个小程序项目同时要用文生图和文生文,统一一个接口省了很多事。如果只是自己玩玩,方案一跑个 demo 也够,别指望它能稳定跑线上就行。

代码都是跑通的,直接复制能用。有问题评论区聊。