Midjourney does not sell an API. No endpoint is documented, no key can be requested, no per-call price list exists, and there is no published rate limit to design against. What exists is a note dated 16 July 2025 saying the company is investigating an Enterprise API, two first-party interfaces, and a licence clause that rules out most of what people mean by “Midjourney API”.
The rest of this page is the evidence, plus code that runs offline against the specifications Midjourney has published.
What Midjourney has actually said about an API
The note is the whole public record: “We’re starting to investigate opening up an Enterprise API for people to start integrating Midjourney into their companies and services. If you’d like to apply, help us figure out what to provide, or just want follow-up updates please fill out our Enterprise API Application.”
Read the wording closely. The verb is investigate, and the note asks applicants to decide what should even be built. There is no endpoint, no key, no per-image price, no quota and no developer documentation. We checked the updates site on 13 September 2026: no later post announced a launch.
Which is why no honest “how to call it” tutorial exists. A guide showing a Midjourney REST request is describing a different product or inventing a surface.
The two interfaces Midjourney ships
Midjourney runs on its website and on Discord, and both are user interfaces rather than integration surfaces. The Discord documentation describes the loop in one sentence: “After submitting a text prompt, the Midjourney Bot processes your request, creating four unique image options within a minute.”
Usage is metered, and the only way to read the meter is a chat command: “each image generation counts towards the GPU time included with your Midjourney subscription. To monitor your available GPU time (Fast Time Remaining) use the /info command.”
Two interfaces, one account, one person. The terms say “Only one user may use the Services per registered account. Each user of the Services may only have one account.” A system that pools accounts to buy throughput is already outside the permitted shape. For the interface path itself, our Midjourney quick-start guide covers the website route, and the Midjourney topic hub collects the rest.
The clause that decides most integrations
Read the licence text before writing code. It contains three statements:
You may not use automated tools to access, interact with, or generate Assets through the Services. You may not resell or redistribute the Services or access to the Service. Only one user may use the Services per registered account. Each user of the Services may only have one account.
Automation and resale of access are both named. A service advertising a Midjourney API is running automated tools against consumer interfaces, and the account risk sits with whoever holds the account.
Two further sentences matter for anything production-facing. Midjourney “reserves the right to suspend or ban Your access to the Services at any time, and for any reason”, and makes no guarantees about “quality, stability, uptime or reliability”. There is no uptime commitment to build a product against. Read the page itself rather than treating this as legal advice.
Parameters you can check before you send anything
Everything below validates locally, which is useful work precisely because the parameters are published even though the API is not.
The three published format rules
The parameter page states three formatting rules, and they are the ones that break prompts in practice:
- Put parameters at the end of the prompt.
- Keep a space between the prompt and the first
--. - Avoid punctuation inside parameters.
The same page lists the full set: --ar, --chaos, --no, --quality, --seed, --stylize, --sref, --tile, --version, --weird, --repeat, --draft and the GPU-speed flags --fast, --relax and --turbo. One entry carries a warning worth propagating into your tooling: --oref is annotated as replaced by the Edit Model in V8.X.
The aspect-ratio rules
The default is 1:1. --ar cannot contain decimals, so 1.39:1 has to be written 139:100, and extremely wide or tall ratios are flagged as experimental. The version page puts numbers on the ceiling: 14:1 for V8.1 and V8.2, and 4:1 for HD.
#!/usr/bin/env bash
# Assemble and check a Midjourney prompt against the rules the official
# parameter and aspect-ratio pages state. Runs offline.
set -uo pipefail
prompt="a weathered fishing boat in a harbour at dawn"
params=(--ar 16:9 --v 8.2 --stylize 250 --chaos 10)
ceiling=14 # Version page: max aspect ratio 14:1 for V8.1 and V8.2
if [[ "$prompt" == *"--"* ]]; then
echo "rejected: the prompt itself contains --, so parameters cannot come last" >&2
exit 1
fi
if (( ${#params[@]} % 2 != 0 )); then
echo "rejected: every parameter needs a value" >&2
exit 1
fi
for ((i = 0; i < ${#params[@]}; i += 2)); do
flag="${params[i]}"
value="${params[i + 1]}"
if [[ "$value" == *","* || "$value" == *";"* ]]; then
echo "rejected: $flag carries a separator; the docs ask for no punctuation" >&2
exit 1
fi
case "$flag" in
--ar)
if [[ "$value" == *.* ]]; then
echo "rejected: --ar cannot contain decimals; write 139:100, not 1.39:1" >&2
exit 1
fi
width="${value%%:*}"
height="${value##*:}"
if [[ "$width" == "$value" || ! "$width" =~ ^[0-9]+$ || ! "$height" =~ ^[0-9]+$ ]]; then
echo "rejected: --ar needs two positive integers, like 16:9" >&2
exit 1
fi
if (( width > height * ceiling )); then
echo "rejected: --ar is wider than the documented ${ceiling}:1 ceiling" >&2
exit 1
fi
;;
--v)
if [[ "$value" != "7" && "$value" != "8.1" && "$value" != "8.2" ]]; then
echo "rejected: --v $value is not a version the version page lists" >&2
exit 1
fi
;;
--stylize|--s|--chaos|--c)
if [[ ! "$value" =~ ^[0-9]+$ ]]; then
echo "rejected: $flag needs a whole number; the docs publish no range for it" >&2
exit 1
fi
;;
esac
done
printf '%s %s\n' "$prompt" "${params[*]}"
The same rules as a runnable Python validator
The shell version handles one prompt. This one belongs in a test suite, because a template that silently drifts stays invisible until a batch of renders is useless.
Note what the script refuses to check. The parameter page publishes no numeric range for --stylize or --chaos, so the code rejects a value it cannot read as a whole number instead of enforcing a range it never saw documented. Guessing a boundary is how invented specs spread.
"""Check a Midjourney prompt string against the published rules. Offline."""
import re
ASPECT_FLAGS = {"--ar", "--aspect"}
def check(raw: str, ceiling: int = 14) -> str:
"""Return the prompt unchanged if it passes, raise ValueError otherwise."""
if " --" not in raw:
raise ValueError("a space must separate the prompt from the first --")
_prompt, _, tail = raw.partition(" --")
tokens = ("--" + tail).split()
if len(tokens) % 2:
raise ValueError("every parameter needs a value")
for flag, value in zip(tokens[::2], tokens[1::2]):
if any(character in value for character in ",;"):
raise ValueError(f"{flag}: no punctuation inside a parameter")
if flag in ASPECT_FLAGS:
if "." in value:
raise ValueError("--ar cannot contain decimals: write 139:100")
ratio = re.fullmatch(r"(\d+):(\d+)", value)
if ratio is None:
raise ValueError("--ar takes two integers, like 16:9")
width, height = (int(part) for part in ratio.groups())
if width > height * ceiling:
raise ValueError(f"--ar is wider than the {ceiling}:1 ceiling")
elif flag in {"--v", "--version"} and value not in {"7", "8.1", "8.2"}:
raise ValueError(f"--v {value} is not a version the version page lists")
return raw
print(check("a weathered fishing boat in a harbour at dawn --ar 16:9 --v 8.2 --stylize 250"))
for bad in (
"a harbour --ar 1.39:1",
"a harbour --ar 20:1",
"a harbour --v 9",
"a harbour --ar 16:9,",
"a harbour--ar 16:9",
):
try:
check(bad)
except ValueError as error:
print("rejected:", error)
The published pixel table, written as assertions
Output size is the one spec Midjourney documents per aspect ratio, so it is the one worth pinning in code. These are the published V8.2 figures, with the page’s own footnote that exact HD pixels “may vary slightly” in some ratios.
| Aspect ratio | V8.2 standard | V8.2 upscaled / HD |
|---|---|---|
| 1:1 | 1024 × 1024 | 2048 × 2048 |
| 4:3 | 1232 × 928 | 2464 × 1856 |
| 2:3 | 896 × 1344 | 1792 × 2688 |
| 16:9 | 1456 × 816 | 2912 × 1632 |
"""The pixel table from Midjourney's upscaler page, checked by assertion."""
# As published for V8.2, one row per aspect ratio. The page adds that exact HD
# pixels "may vary slightly" in some aspect ratios.
SAMPLES = {
"1:1": {"sd": (1024, 1024), "hd": (2048, 2048)},
"4:3": {"sd": (1232, 928), "hd": (2464, 1856)},
"2:3": {"sd": (896, 1344), "hd": (1792, 2688)},
"16:9": {"sd": (1456, 816), "hd": (2912, 1632)},
}
# Version page: HD costs 1.3 minutes of GPU time against 0.8 for a standard job.
GPU_MINUTES = {"sd": 0.8, "hd": 1.3}
for ratio, row in SAMPLES.items():
width_sd, height_sd = row["sd"]
width_hd, height_hd = row["hd"]
assert width_hd == width_sd * 2, ratio
assert height_hd == height_sd * 2, ratio
assert width_sd % 8 == 0 and height_sd % 8 == 0, ratio
assert SAMPLES["1:1"]["sd"] == (1024, 1024) # the documented default square
assert SAMPLES["1:1"]["hd"] == (2048, 2048) # HD cannot be upscaled further
assert round(GPU_MINUTES["hd"] / GPU_MINUTES["sd"], 3) == 1.625 # +62.5%
# What one 16:9 HD render costs in plan allowance, in minutes:
print(f"16:9 HD is {SAMPLES['16:9']['hd'][0]}x{SAMPLES['16:9']['hd'][1]}px "
f"for {GPU_MINUTES['hd']} GPU minutes")

Two facts fall out of the table. A standard render is already 1024 pixels on its short side at 1:1, which is why the U buttons no longer upscale. And HD costs 1.3 GPU minutes against 0.8, so an HD batch spends about 62% more of your allowance per image; the documentation also warns that upscaling a standard job “can cost twice as many GPU minutes as generating your initial images.”
Third-party gateways, and what they are actually doing
Search for a Midjourney API and you will find vendors selling one. What they sell is automated access to an account, dressed as a service. Some publish per-image prices; those are that site’s own quotes, not Midjourney’s, and they move without notice because the cost underneath them is a subscription.
Three questions separate a tolerable arrangement from a fragile one. Does the vendor admit that no official API exists? Who holds the account that gets suspended if enforcement lands? And does the output licence reach you, given that ownership is tied to a subscription in a named account?
If you need a programmatic image surface, pick a product that publishes one. Self-hosted Stable Diffusion removes the interface question entirely, and GPT Image 2.5 is a first-party image model with public endpoints and prices.
What is still not published
Every item on this list gets filled in with a guess somewhere online.
- Endpoints, request or response schemas, and any base URL.
- API keys: how to request one, how they rotate.
- Per-call pricing, credit packs, and whether API usage would consume GPU minutes.
- Rate limits, concurrency ceilings and queue behaviour.
- Uptime, latency and support commitments.
- Whether an Enterprise API, if it ships, reaches below enterprise scale.
- The training data behind the model.
Frequently asked questions
Does Midjourney have an official API? No. The only official statement is the 16 July 2025 note describing an Enterprise API as under investigation, with nothing published since.
Can I use Midjourney programmatically at all? The licence prohibits automated tools for accessing, interacting with, or generating assets through the services, and prohibits reselling access. Anything built around that puts the account at risk.
Are the third-party “Midjourney API” services legitimate? They are not official, and Midjourney publishes nothing authorising them.
Is there anything useful I can build today? Validate parameters locally, keep the published pixel and compute figures in one asserted table, and let CI reject a prompt that breaks the documented format rules.
The Midjourney API question has a stable answer for now, and it is a negative one: write your tooling against the specs that are published, keep the licence text in view.