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}")
这套方案的坑,真的多
- Discord 交互命令鉴权变了:2026 年 Discord 把 Interaction 端点的鉴权收紧了,Bot Token 直接调
/interactions会 403,得用 User Token 模拟——但这违反 Discord ToS,号随时可能被封 - 轮询逻辑不靠谱:MJ 生成过程中会发多条消息(进度 25%、50%、100%),你得判断哪条是最终结果,光靠「有没有 png 附件」不够,还得检查消息内容里有没有
(fast)或(relaxed)标记 - 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 也够,别指望它能稳定跑线上就行。
代码都是跑通的,直接复制能用。有问题评论区聊。
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
Docker Compose部署多.NET后端API+多Vue前端Web 完整记录(含多数据库扩展+实用场景,亲测无坑)
Vue Router常用内容总结
多模融合重塑文档数据库:金仓数据库 MongoDB 兼容版的技术实践
mysql核心算法详细解析
前端权限控制设计
【Vue】侦听器:watch与watchEffect的区别与使用
不再隐藏变更:MySQL 9.6 如何变革外键管理
金仓赋能:关系数据库替换高效落地,Oracle 平滑迁移
她问我:数据库还在存 Timestamp?我说:大人,时代变了
我尝试将TinyPro集成TinyEngine低代码设计器了
AI精选
