You typed "midjourney rest api documentation" and probably landed on a wrapper's dev page: one curl example, a bearer token you rent per month, and no story for what happens when a job fails. That gap isn't an accident. Midjourney has no official REST API — everything you find is a third-party layer, and most of those layers document the happy path and stop there. This guide covers what production Midjourney REST API docs should actually contain: the endpoint surface, the auth model, and the error semantics that separate an API from a script with a URL.
The framing matters. A midjourney rest api documentation page for a thin wrapper lists a POST /generate endpoint and a polling callback. Production API docs list a job lifecycle, webhooks, rate-limit codes, and per-account backoff. The difference is whether the API survives load — and that's what this guide is about.
Nextjourney is not affiliated with Midjourney or Discord. There is no official Midjourney API; every "Midjourney REST API" in the wild works through Discord user accounts, which sits outside Discord's Terms of Service. That risk applies equally to wrappers and self-hosted platforms. Details in our post on why Midjourney has no official API.
What real midjourney rest api documentation covers
Strip away the marketing and a serious API surface has the same skeleton no matter who wrote it:
- A submit endpoint — you send a prompt, get back a job id, not the image.
- A job status endpoint — you query progress, or get pushed a webhook.
- An auth model — API keys or bearer tokens, with scopes and rotation.
- Error semantics — distinct responses for rate limits, bad prompts, dead sessions, and queued jobs.
That's the whole shape. Three endpoints and an auth header, if you're generous. The depth is in the last two: how auth works and how errors are represented. Most wrapper docs get away with hand-waving both.
# The honest shape of a generation API call
curl -X POST https://api.example.com/v1/generate \
-H "Authorization: Bearer sk-live-xxxx" \
-H "Content-Type: application/json" \
-d '{"prompt":"cyberpunk street market at night, rain, neon"}'
# => 202 Accepted, location: /v1/jobs/job_9f2c
Midjourney API authentication: keys, tokens, rotation
Because there's no official API, "authentication" for a Midjourney REST API is really two layers: your API key (how your app talks to the platform) and the Discord/Midjourney account session underneath (how the platform actually submits jobs). Wrapper docs blur these and it matters.
Your API key is what you secure. Two patterns:
- Static key with rotation — fine for internal use, but the aftermath of a leaked key is a manual revoke across every integration.
- Scoped tokens — mint short-lived tokens for each client, so a breach in one app doesn't leak a master credential.
The second is what production platforms do. The underlying account session is the platform's problem, not yours — that's the whole point of using an API, and it's covered properly in the account rotation guide.
For the credential boundary itself, see our focused guide to Midjourney API authentication, including scoped tokens, headers, and revocation.
// Scoped-token exchange — don't hard-code the master key in clients
const res = await fetch("https://yourdomain.com/api/token", {
method: "POST",
headers: { "X-API-Key": process.env.MASTER_KEY },
body: JSON.stringify({ clientId: "agency-workspace" }),
});
const { access_token } = await res.json();
The rule: your app holds a master key server-side, clients get scoped tokens, and generation calls carry the scoped token. Any doc that tells you to ship the master key into a mobile app or a browser is a doc you should not follow.
Midjourney REST API error handling: the codes people skip
The single biggest gap between hobby middleware and a real API is how errors are represented. A thin wrapper returns {"error": "failed"} and calls it done. A production API returns distinguishable states so your code can react:
- 429 Rate Limited — you're hitting concurrency or per-account limits. The response should carry a
Retry-After. Back off, don't hammer. - 400 Rejected — the prompt tripped a filter or the account rejected it. Retrying the same payload is pointless; it needs a change.
- 503/504 Upstream — Discord or Midjourney is degraded or a worker is overwhelmed. This is transient; exponential backoff retry.
- 401/403 Auth — expired token or dead session. This is a refresh flow, not a retry loop — retry here multiplies a limp session.
// React to the codes that matter, not just "error"
async function generate(client, prompt) {
while (true) {
const res = await client.post("/v1/generate", { prompt });
if (res.status === 202) return res.body.jobId; // accepted
if (res.status === 429) { await sleep(res.retryAfter); continue; }
if (res.status === 400) throw new PromptRejected(res.body); // permanent, no retry
if (res.status >= 500) { await sleep(backoff()); continue; } // upstream, retry
throw new Unexpected(res.status);
}
}
The lesson: not every error is a retry, and not every retry has the same backoff. Pasting the same payload into a loop because "your wrapper said it handles retry" is how you burn a session and get nowhere.
Where the documentation actually lives
For whatever you chose — a wrapper you rent or a self-hosted platform you run — the quality bar is the same. Does the API surface match what's on this page: POST generate, job status, webhooks, scoped auth, and real error codes? Most rentals don't, because they amortize their thin docs across thousands of users. A self-hosted platform, by contrast, means the API and its docs arrive with the source code, so you can read the actual error-handling logic instead of guessing from a vague reference. If the consumer is a browser app, the Midjourney API React integration guide applies this same job lifecycle without exposing credentials.
Ready to self-host?
Full source code — backend, frontend, REST API, admin dashboard. One-time license from $399, no recurring platform fees.
See pricingThe API is only as good as its failure story
Here's the honest bottom line: a Midjourney REST API is three endpoints and an auth header. The part that makes you money is the retries, rate-limit codes, and session handling around them. If the docs you're reading stop at "here's a curl," keep looking — production docs show the failure states, because that's where the cost of a bad integration hides.