Your first authentication mistake is usually architectural: putting a provider key in a frontend bundle because the demo needs one request. That key will be copied, replayed, and eventually revoked. Midjourney API authentication needs a server-side boundary, scoped credentials, and a clear distinction between your API key and the account session underneath it.
Nextjourney is not affiliated with Midjourney or Discord. Midjourney has no official public API; wrappers and self-hosted platforms operate through third-party account automation and carry the relevant Terms of Service risk. See our guide to whether Midjourney has an official API.
How Midjourney API authentication actually works
There are two credentials in the typical request path:
- Your application credential — a key or bearer token that lets your app call the generation platform.
- The upstream account session — the Discord/Midjourney session used by the platform worker to submit the job.
Your product should only handle the first. The second belongs in a restricted worker or provider vault, never in a browser, mobile app, or customer-facing log. This separation is the difference between revoking one client key and rebuilding an entire account pool after a leak.
The public request should look ordinary:
curl -X POST https://api.example.com/v1/generate \
-H "Authorization: Bearer $IMAGE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"prompt":"editorial product photo, soft studio light --ar 16:9"}'
The token authenticates your application to the API layer. It does not make the endpoint an official Midjourney API, and it should not be confused with a raw Discord token.
Midjourney API keys: choose the smallest useful scope
A single master key is convenient until three people, two environments, and one contractor are using it. Then you cannot answer basic questions: who made this request, which integration leaked, and what can you revoke without taking production down?
Use separate credentials for separate jobs:
- Environment: development, staging, and production should not share a key.
- Tenant or client: an agency integration should be revocable without affecting another client.
- Permission: a generation-only token should not manage accounts, billing, or admin settings.
- Lifetime: short-lived access tokens reduce the blast radius of accidental exposure.
A practical internal token record might contain token_hash, tenant_id, scopes, created_at, expires_at, and revoked_at. Store a hash for lookup and revocation; do not store a plaintext copy merely because it is easier to debug.
If you are building the platform yourself, the same pattern belongs in the admin dashboard: create a token, show it once, assign scopes, and make revocation explicit. The Midjourney REST API guide shows how this auth layer fits beside generation, job-status, and webhook endpoints.
Token headers: keep secrets out of clients and logs
The standard header is simple:
Authorization: Bearer eyJ...
Content-Type: application/json
The security work is around that header. Terminate TLS, reject missing or malformed tokens before queueing a job, and redact Authorization from access logs. Do not include tokens in query parameters: URLs spread into browser history, reverse-proxy logs, analytics, and referrer headers.
Your browser can call your own backend instead:
// Browser: no provider key here
const response = await fetch("/api/image-jobs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt })
});
// Server: authenticate the user, then add the provider token
const upstream = await fetch(`${IMAGE_API_URL}/v1/generate`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.IMAGE_API_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ prompt: req.body.prompt })
});
The browser-facing route still needs its own user authentication, input limits, and quota checks. Hiding the provider key does not stop an anonymous visitor from spending your generation budget if /api/image-jobs is public.
Rotation and revocation are part of the API design
Rotation should be boring. Support two active keys during a cutover: issue the replacement, deploy it, verify requests, then revoke the old key. A hard switch that invalidates the old token before workers restart creates avoidable downtime.
For upstream account sessions, rotation is different. A session may be expired, disconnected, rate-limited, or manually revoked. Treat a 401 or 403 as a health event, not a reason to retry the same credential forever. The account safety guide covers the operational side; your API should expose a clear failure state so the queue can pause or route to another eligible worker.
Do not rotate credentials in response to every transient 429. Back off according to the provider response, preserve the job id, and retry within a bounded budget. Excessive rotation hides a concurrency problem and makes session health harder to diagnose.
A small authentication checklist for production
Before shipping, verify five paths:
- A valid scoped token can submit a job and read only the resources it needs.
- An expired or revoked token gets
401, without queueing upstream work. - A token for tenant A cannot read tenant B's job status or image URL.
- Logs, traces, error payloads, and analytics contain no bearer credential.
- Replacing a production token does not require exposing an upstream account session.
This is not a claim that the underlying third-party automation is risk-free. It is simply the minimum boundary that keeps an application credential from becoming an account credential.
Ready to self-host?
Full source code — backend, frontend, REST API, admin dashboard. One-time license from $399, no recurring platform fees.
See pricingAuthentication is a boundary, not a header
The Authorization header is the visible part. The real design is scoped access, server-side secrets, revocation, and workers that can report upstream session health without leaking it. If you need those pieces together, compare the self-hosted deployment path before adopting a rented wrapper.