Skip to content

Midjourney

Generate images with Midjourney asynchronously: parameters, results, and caveats.

ItemValue
Base URLhttps://api.hop-base.com/v1
Submit a taskPOST /v1/images/generations
Query a taskGET /v1/video/tasks/{task_id}
List tasksGET /v1/video/tasks
Key groupMidjourney Image Generation

Midjourney is an asynchronous API: submit a task to get a HopBase task ID, then poll it for the result; every task returns exactly four images, and each one is billed.

Available models

ModelModel IDTier / sizeOfficial price
Midjourney v8.2midjourney-v8-21K by default; native 2K with --hd$0.0067from/ image

Confirm the exact model ID available to your key with GET /v1/models before sending paid work.

Request parameters

All requests use Authorization: Bearer sk-your-key and Content-Type: application/json. Size and quality go in -- parameters at the end of the prompt, not in request fields.

Body fields

ParameterRequiredType and limitsDefaultDescription
modelRequiredstring, exact match—midjourney-v8-2
promptRequiredstring with a description—Add -- parameters after it
imagesOptionalarray of 0–1 items—Reference image
nOptionalonly 44Every task returns four images
qualityOmitmust be empty—Use --hd for 2K
extraOmitmust be empty—No extra parameters
  • prompt must contain a description, not only -- parameters, and no ::; images without a description are rejected.
  • images is a reference image, for example [{"url":"https://example.com/ref.png"}]. It takes one image; for several, see “Multiple reference images” below.
  • Each images[] item has exactly one of url (public absolute HTTP(S)) or file_id, and no usage.
  • A non-empty quality returns 400; use --hd in the prompt for 2K.
  • A non-empty extra object returns 400; this model takes no extra parameters.
Only the fields above are accepted; anything else is a 400.

The body is decoded strictly: any field not in the table is rejected with 400 at submission, no task is created, and nothing is billed. Set the aspect ratio with --ar in the prompt and the quality with --hd.

Fields that OpenAI Images clients often send, such as size, response_format, and style, are outside the table; the full list is under "More details" in Caveats below.

Size and aspect ratio

Image size comes from --ar (or its alias --aspect) in the prompt. --hd renders natively at roughly twice the edge length.

Any whole-number ratio works, not just the ones listed — as long as neither direction exceeds 14:1 (4:1 with --hd). The table lists common ratios; every size was measured, not derived — --hd is not an exact doubling.

--arDefaultWith --hd
1:1 (default)1024 × 10242048 × 2048
1:2768 × 15361552 × 3104
9:16816 × 14561648 × 2944
2:3896 × 13441792 × 2688
3:4928 × 12321904 × 2544
5:6992 × 12002016 × 2416
6:51200 × 9922416 × 2016
4:31232 × 9282544 × 1904
3:21344 × 8962688 × 1792
16:91456 × 8162944 × 1648
2:11536 × 7683104 × 1552
21:91680 × 7203376 × 1440
14:14096 × 288Rejected — see below
  • --ar takes exactly one width:height value made of positive whole numbers; --ar 1.5:1 is rejected.
  • The ratio may not exceed 14:1 in either direction.
  • --hd lowers that ceiling to 4:1: --hd --ar 14:1 is rejected, while --hd --ar 4:1 renders at 4096 × 1184.

Prompt parameters

These are accepted and passed through:

ParameterRangePurpose
--ar / --aspectwhole ratioAspect ratio
--hdflagNative 2K render
--s / --stylize0-1000Stylization strength
--c / --chaos0-100Variation across the four images
--weird / --w0-3000Unconventional aesthetics
--iw0-3Weight of the reference image
--sref + --sw--sw 0-1000Style reference and its strength
--notextExclude elements
--seedintegerReproducibility
--tile, --expflag / 0-100Seamless tiling; dynamic range
  • Put every parameter after the description: any text after the first -- parameter is read as that parameter's value.
  • A numeric parameter with a range must be followed by exactly one number; a missing, extra, non-numeric, or out-of-range value returns 400.

Multiple reference images

images takes one image. To use several, put their URLs at the very start of prompt, separated by spaces, followed by your description — this is Midjourney's standard Image Prompt syntax:

"prompt": "https://example.com/a.png https://example.com/b.png a cat sitting in a vintage car --ar 1:1"

  • Every URL must be a public HTTP(S) address.
  • Reference images are inspiration, not a collage: their influence is not evenly split, and a strong subject in one image can dominate the result.
  • To make sure something from a particular image shows up, name it in the description, or raise --iw (0-3) to give the reference images more weight.

Refused parameters

These are rejected with 400 at submission. The model would otherwise ignore them silently, leaving you paying for an effect you never got, or fail the task minutes later.

ParameterWhy
--q / --qualityHas no effect on this model version
--nijiNiji is a separate model version, not a parameter here
--repeatHas no effect; the image count per task is fixed
--oref, --crefOmni and character reference are unavailable on v8.x
--stealth, --stopNot supported on this model version
--relax, --turboTasks always run in Fast mode: Relax is not offered through this API, and Turbo is unavailable on v8.x
--draftReturns 24 low-resolution images per task; not offered
--profile / --pPersonalization profiles are not supported here
::Multi-prompt weighting is not supported on this model version

Response

Submit response

A successful submit returns HTTP 202:

FieldTypeDescription
idstringHopBase task ID to poll
objectstringAlways image.generation.task
modelstringmidjourney-v8-2
statusstringStarts as queued
createdintegerCreation time (Unix seconds)
billing_bucketstringDefault tier or the --hd 2K tier
requested_imagesintegerAlways 4
images_per_taskintegerAlways 4
noticestringReminder: four images, each billed
{
  "id": "ktEXAMPLE",
  "object": "image.generation.task",
  "model": "midjourney-v8-2",
  "status": "queued",
  "created": 1790000000,
  "billing_bucket": "img_1k",
  "requested_images": 4,
  "images_per_task": 4,
  "notice": "this model always returns 4 images per task and bills every returned image"
}

Query result

status moves through queued → processing → completed or failed. Only the last two are terminal, so treat any other value as still running.

FieldTypeDescription
idstringTask ID
objectstringAlways video.generation.task, image tasks included
statusstringqueued / processing / completed / failed
outputsstring[]Four image URLs once completed, valid 24 hours
usageobjectMetering once completed: bucket (the tier from submit) and billed_images (always 4)
usage.costnumberThe charge for this task in CNY (the same charge as usage.cost_usd)
usage.cost_usdnumberThe USD amount actually deducted from your balance for this task, the same as its usage record
usage.currencystringThe currency of usage.cost, always CNY
error.codestringStable error code on failure
error.messagestringEnglish explanation of the failure

An excerpt of a completed task; the ID and URLs are placeholders:

{
  "id": "ktEXAMPLE",
  "object": "video.generation.task",
  "model": "midjourney-v8-2",
  "status": "completed",
  "created": 1790000000,
  "outputs": [
    "https://api.hop-base.com/example-signed-image-1.png",
    "https://api.hop-base.com/example-signed-image-2.png",
    "https://api.hop-base.com/example-signed-image-3.png",
    "https://api.hop-base.com/example-signed-image-4.png"
  ],
  "usage": { "bucket": "img_1k", "billed_images": 4, "cost": 0.1496, "cost_usd": 0.022, "currency": "CNY" }
}

The output URLs are served from api.hop-base.com as signed links valid for 24 hours from the moment the task completes. Querying again returns the same URL without extending it, and an expired link returns 410, so download the images in time.

Once the task finishes, the query's top-level usage also carries cost_usd — the USD amount actually deducted from your balance for this task, 0 for an uncharged failure — cost (the same charge in CNY), and currency (always CNY); see Video generation. The task list (GET /v1/video/tasks) carries the same cost, cost_usd, and currency in the usage of every finished task.

Examples

Submit a 16:9 task, then poll it to a terminal state:

curl https://api.hop-base.com/v1/images/generations \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "midjourney-v8-2",
    "prompt": "a red apple on a wooden table, studio light --ar 16:9"
  }'

# Poll with the returned id; send no billing header
curl https://api.hop-base.com/v1/video/tasks/YOUR_TASK_ID \
  -H "Authorization: Bearer sk-your-key"

Caveats

  • Every task returns four images and each is billed, so budget for four images per submission.
  • n accepts only 4 or nothing at all.
  • Set the ratio with --ar and 2K with --hd; size or quality in the body returns 400.
  • With --hd, the aspect-ratio ceiling drops from 14:1 to 4:1.
  • Put every -- parameter after the description.
  • Concurrency is limited: submitting a large batch in parallel fails most of it rather than queueing it.
  • A task still unfinished 2 hours after creation is marked failed and not billed.
Content moderation is strict.

Even in fashion or commercial portraits, detailed descriptions of body shape, figure, or body parts such as legs, or emphasis on close-fitting or sheer clothing, can be refused when they add up. Describe the overall look, style, setting, and lighting instead, and submit again.

Common errors

Every submission-time error is HTTP 400; no task is created and nothing is billed. Checks run in order and the first failure is returned, in this body:

{
  "error": {
    "message": "request body does not match the JSON contract: json: unknown field \"size\"",
    "type": "invalid_request_error"
  }
}
ErrorFix
json: unknown field "size"Remove the extra field; set the ratio with --ar
the quality field has no effect on this modelRemove quality; use --hd for 2K
the n field cannot change thatOmit n or set it to 4
prompt must contain a descriptionAdd a description before the parameters
parameter --draft is not acceptedRemove the refused parameter
may not exceed 4:1 when --hd is usedNarrow the ratio, or drop --hd

Failed tasks

A failed task still answers the query with HTTP 200 and status failed. Decide success or failure from status, branch on error.code, and show error.message.

Causeerror.codeWhat to do
Prompt refused by moderationinput_sensitiveRephrase the prompt and resubmit
Reference image refused by moderationinput_sensitiveSwap the reference image and resubmit
Moderation, source not reportedinput_sensitiveRephrase; swap the reference image if sent
Concurrency ceiling reachedrate_limitedRetry shortly; run fewer tasks at once
No descriptionprompt_requiredAdd a description
Unsupported parameterinvalid_requestRemove the parameter not in the supported list
Invalid aspect ratioinvalid_requestUse a whole-number ratio within the ceiling
Malformed promptinvalid_requestCheck the trailing parameters and their values
Generation failed (other)generation_failedRetry once; then contact support with the task ID
Task could not be trackedgeneration_failedContact support with the task ID
Timed outtimeoutResubmit
Finished with no outputno_outputResubmit

Billing

Midjourney bills per returned image, so a task costs four images at the rate for its tier; the default render and the --hd 2K render are priced separately. Only a task that completes successfully is billed; rejected submissions, moderation refusals, and failed tasks are not.

Official list prices are on the pricing page. Your own rate is the one shown in the signed-in model catalog, and each request's actual charge is in your usage record.

The model's specs and official prices are also on its model card.

Next steps