ApiframeApiframe Docs
Follow-up ActionsMidjourney

Inpaint

Repaint a masked region of an upsampled Midjourney image (Vary Region).

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

Equivalent to Midjourney's Vary (Region) button: repaints only the area of an upsampled image covered by your mask, optionally guided by a new prompt. The result is a fresh 4-image grid of candidates, each of which can be upsampled again.

Request

ParameterTypeRequiredDescription
parentJobIdstring (uuid)YesID of the completed upsample job to act on
actionstringYes"inpaint"
maskstring (base64)YesBlack-and-white mask image, same dimensions as the parent image. White = repaint, black = preserve. An optional data:image/...;base64, prefix is accepted and stripped. Max ~8 MB decoded.
promptstringNoWhat to render in the repainted region (max 2000 chars). Omit to let Midjourney re-imagine the region from the original prompt.
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 completed upsample action job — inpainting a 4-up grid directly returns 400; upsample one image first.

The mask is uploaded to our CDN for processing and deleted as soon as the job completes or fails — it is never stored with the job, and it is not echoed back in the job's input.

Credits

16 credits per inpaint.

Example result

Once the job is COMPLETED, the result object on GET /v2/jobs/:id contains a new 4-image grid:

{
  "images": [
    "https://cdn2.apiframe.ai/images/b2c3d4e5-...-1.png",
    "https://cdn2.apiframe.ai/images/b2c3d4e5-...-2.png",
    "https://cdn2.apiframe.ai/images/b2c3d4e5-...-3.png",
    "https://cdn2.apiframe.ai/images/b2c3d4e5-...-4.png"
  ],
  "gridUrl": "https://cdn2.apiframe.ai/images/b2c3d4e5-...-grid.png"
}

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\": \"inpaint\",
    \"mask\": \"$(base64 -i mask.png)\",
    \"prompt\": \"a red hot air balloon\"
  }"
import base64
import requests

with open("mask.png", "rb") as f:
    mask = base64.b64encode(f.read()).decode()

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": "inpaint",
        "mask": mask,
        "prompt": "a red hot air balloon",
    },
)
print(response.json())
import { readFile } from "node:fs/promises";

const mask = (await readFile("mask.png")).toString("base64");

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: "inpaint",
    mask,
    prompt: "a red hot air balloon",
  }),
});
console.log(await response.json());
maskBytes, _ := os.ReadFile("mask.png")
mask := base64.StdEncoding.EncodeToString(maskBytes)

payload, _ := json.Marshal(map[string]string{
    "parentJobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "action":      "inpaint",
    "mask":        mask,
    "prompt":      "a red hot air balloon",
})
req, _ := http.NewRequest("POST", "https://api.apiframe.ai/v2/images/midjourney/action",
    bytes.NewReader(payload))
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