Skip to content
TutujinAPI

API reference

Midjourney tasks

Asynchronous Midjourney API — submit with POST /mj/submit/imagine and friends, poll GET /mj/task/{id}/fetch for the result. Compatible with the common Midjourney Proxy protocol; examples for upscale, vary, zoom out, vary region, describe and video, with per-call pricing.

Midjourney works as an asynchronous task API, unlike the synchronous OpenAI-format endpoints: submit a task, get its ID, then poll until the image is ready. Paths and fields follow the common Midjourney Proxy protocol, so existing MJ code only needs https://www.tutujin.com as its address and a key from this site.

POSThttps://www.tutujin.com/mj/submit/imagine

Headers

HeaderRequiredDescription
AuthorizationYesBearer sk-..., an API key from the console. The mj-api-secret: sk-... header used by Midjourney Proxy clients works too
Content-TypeYesapplication/json

The body has no model field: each route and action is billed as its own model.

Endpoints

EndpointPurposeBilled as
POST /mj/submit/imagineText to image; base64Array adds reference imagesmj_imagine
POST /mj/submit/actionPress a button on a result: upscale, vary, strong / subtle vary, reroll, zoom out, panmj_upscale, mj_variation, mj_high_variation, mj_low_variation, mj_reroll, mj_zoom, mj_pan
POST /mj/submit/modalSecond step of vary region and custom zoommj_modal
POST /mj/submit/describeImage to promptsmj_describe
POST /mj/submit/editsEdit an image with a promptmj_edits
POST /mj/submit/videoText / image to video, four clips per callmj_video
POST /mj/submit/upload-discord-imagesUpload images and get URLs to use in promptsmj_upload
GET /mj/task/{id}/fetchGet one taskFree
POST /mj/task/list-by-conditionGet several tasks with {"ids": [...]}Free

Prices per operation are in the model list at the bottom of this page and in the model catalog. Operations missing from the catalog (currently Blend, Shorten and face swap) are not supported: such a request answers "no available channel" and is not billed.

Request body

ParameterTypeUsed byDescription
promptstringimagine, edits, video, modalPrompt; Midjourney parameters such as --ar 16:9 are allowed. --fast, --relax and --turbo are ignored: the speed tier is fixed by this site
base64Arrayarrayimagine, uploadImages as data:image/png;base64,...; reference images for imagine
taskIdstringaction, modalID of the earlier task to continue from
customIdstringactionButton ID from the earlier task's buttons; picks the operation
maskBase64stringmodalMask image (base64) for vary region
base64stringdescribeImage (base64) to describe
imagestringedits, videoURL of the reference image or the video's first frame
motionstringvideolow or high

Request example

Submit an imagine task, then poll until status is SUCCESS or FAILURE:

curl https://www.tutujin.com/mj/submit/imagine \
  -H "Authorization: Bearer $TUTUJIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "An orange cat sunbathing by the window, watercolor style --ar 3:2"
  }'

# poll with the task ID returned in "result"
curl https://www.tutujin.com/mj/task/$TASK_ID/fetch \
  -H "Authorization: Bearer $TUTUJIN_API_KEY"

An image usually takes from a few dozen seconds to a couple of minutes. Polling every 3–10 seconds is plenty.

Next steps: upscale, vary, zoom out, pan

A finished task lists the Midjourney buttons in buttons. Send a button's customId together with the task ID to /mj/submit/action; that starts a new task, polled the same way:

cURL
curl https://www.tutujin.com/mj/submit/action \
  -H "Authorization: Bearer $TUTUJIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "taskId": "1794500000000001",
    "customId": "MJ::JOB::upsample::1::2f4a9c1e7b3d5a8f0c6e1b92"
  }'

upsample buttons upscale (U1–U4, 2x / 4x), variation buttons vary (V1–V4), reroll regenerates, Outpaint zooms out and pan_* pans.

Vary region and custom zoom take two steps. First send the Inpaint or CustomZoom button to action: it answers code 21 with a new task ID and is not billed. Then send that ID with a new prompt (plus a maskBase64 mask for vary region) to /mj/submit/modal, billed as mj_modal.

Response example

Submitted:

JSON
{ "code": 1, "description": "Submit success", "result": "1794500000000001" }

Task:

JSON
{
  "id": "1794500000000001",
  "action": "IMAGINE",
  "status": "SUCCESS",
  "progress": "100%",
  "imageUrl": "https://www.tutujin.com/mj/image/1794500000000001",
  "failReason": "",
  "buttons": [
    { "customId": "MJ::JOB::upsample::1::2f4a9c1e7b3d5a8f0c6e1b92", "label": "U1" },
    { "customId": "MJ::JOB::variation::1::2f4a9c1e7b3d5a8f0c6e1b92", "label": "V1" }
  ]
}
FieldDescription
codeSubmit result: 1 accepted; 21 means a modal step follows (vary region, custom zoom); anything else failed, see description
resultTask ID
statusNOT_START, SUBMITTED, IN_PROGRESS, SUCCESS, FAILURE
progressProgress such as 67%
imageUrlThe result image (grid or single upscale), served through this site's domain; download it soon
videoUrlsVideo URLs of a video task
promptEnPrompts produced by describe
buttonsOperations available next
failReasonWhy the task failed

Billing

  • Per call: every operation is billed as its own model, priced in the list below. Only an accepted submit (code 1) is charged; a rejected submit costs nothing, and a task that ends in failure is refunded.
  • Every upscale button (U1–U4, 2x, 4x) is billed as mj_upscale and zoom out as mj_zoom, so all buttons of one model cost the same.
  • The first step of vary region / custom zoom is free; the second is billed as mj_modal.
  • Polling is free.

Notes

  • The API is asynchronous: do not hold one HTTP request open for the result. Store the task ID and poll, or check back later.
  • Callbacks are not supported (notifyHook is ignored); poll for results.
  • The speed tier is fixed by this site, so --fast, --relax and --turbo in a prompt have no effect.
  • A prompt that trips Midjourney's moderation fails at submit or ends as FAILURE. Change the prompt and submit again.
  • Image URLs are for short-term use; download results into your own storage.

Models that support this endpoint

ModelVendorCheapest groupInput ¥/1MOutput ¥/1MPer request ¥
Midjourney UploadMidjourneyStandard——¥0.02
Midjourney DescribeMidjourneyStandard——¥0.1
Midjourney ImagineMidjourneyStandard——¥0.4
Midjourney VariationMidjourneyStandard——¥0.4
Midjourney Vary (Strong)MidjourneyStandard——¥0.4
Midjourney Vary (Subtle)MidjourneyStandard——¥0.4
Midjourney RerollMidjourneyStandard——¥0.4
Midjourney UpscaleMidjourneyStandard——¥0.4
Midjourney Zoom OutMidjourneyStandard——¥0.4
Midjourney PanMidjourneyStandard——¥0.4
Midjourney Vary Region / Custom ZoomMidjourneyStandard——¥0.4
Midjourney EditMidjourneyStandard——¥0.4
Midjourney VideoMidjourneyStandard——¥2.8

Prices in CNY, cheapest group for each model; updated Nov 13, 2026, 6:13 PM.

Still stuck? Add our WeChat support JsnonoChat and send the request id from the error message, and we will look into it.