ApiframeApiframe Docs
Follow-up ActionsMidjourney

Variations

Generate a fresh 4-image grid riffing on one image of a completed Midjourney grid (V1–V4).

POST /v2/images/midjourney/actionaction: "variation"

Equivalent to Midjourney's V1–V4 buttons: takes one of the 4 images from a completed Midjourney generation and generates a fresh 4-image grid of variations on it.

Request

ParameterTypeRequiredDescription
parentJobIdstring (uuid)YesID of the completed Midjourney job to act on
actionstringYes"variation"
indexintegerYesWhich image of the grid to vary (1–4, matching V1–V4)
webhookUrlstringNoHTTPS URL that receives a JSON POST when the job reaches a subscribed event — see Webhooks for payload formats
webhookEventsstring[]NoEvents to be notified about: "progress", "completed", "failed". Defaults to ["completed", "failed"] when webhookUrl is set

The parent must be a Midjourney generation or variations job with status COMPLETED. Varying an upsample result returns 400 (use Inpaint, Outpaint, or Pan instead); parents created before follow-up actions were introduced return 409.

Credits

16 credits per variation — it regenerates a full 4-image grid, the same upstream work as a generation.

Example result

The result has the same shape as a generation — 4 images plus a 2×2 composite grid:

{
  "images": [
    "https://cdn2.apiframe.ai/images/a1b2c3d4-e5f6-7890-abcd-ef1234567890-1.png",
    "https://cdn2.apiframe.ai/images/a1b2c3d4-e5f6-7890-abcd-ef1234567890-2.png",
    "https://cdn2.apiframe.ai/images/a1b2c3d4-e5f6-7890-abcd-ef1234567890-3.png",
    "https://cdn2.apiframe.ai/images/a1b2c3d4-e5f6-7890-abcd-ef1234567890-4.png"
  ],
  "gridUrl": "https://cdn2.apiframe.ai/images/a1b2c3d4-e5f6-7890-abcd-ef1234567890-grid.png"
}

Because the result is a grid, it can itself be acted on — chain another variation or upsample using the new job's ID as parentJobId.

Code examples

curl -X POST https://api.apiframe.ai/v2/images/midjourney/action \
  -H "X-API-Key: afk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "parentJobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "action": "variation",
    "index": 1
  }'
import requests

response = requests.post(
    "https://api.apiframe.ai/v2/images/midjourney/action",
    headers={
        "X-API-Key": "afk_your_api_key_here",
        "Content-Type": "application/json",
    },
    json={
        "parentJobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "action": "variation",
        "index": 1,
    },
)
print(response.json())
const response = await fetch("https://api.apiframe.ai/v2/images/midjourney/action", {
  method: "POST",
  headers: {
    "X-API-Key": "afk_your_api_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    parentJobId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    action: "variation",
    index: 1,
  }),
});
console.log(await response.json());
body := `{
  "parentJobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "action": "variation",
  "index": 1
}`
req, _ := http.NewRequest("POST", "https://api.apiframe.ai/v2/images/midjourney/action",
    strings.NewReader(body))
req.Header.Set("X-API-Key", "afk_your_api_key_here")
req.Header.Set("Content-Type", "application/json")

resp, err := http.DefaultClient.Do(req)

Try it

POST/v2/images/midjourney/actionTry it

On this page