---
title: "Edit a masked region of an image (async)"
method: POST
path: "/v1/images/region-edit"
tags: ["Images"]
---

# Edit a masked region of an image (async)

`POST /v1/images/region-edit`

## Request

- Base URL: `https://contentmaschine.ai/api`
- URL: `https://contentmaschine.ai/api/v1/images/region-edit`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://contentmaschine.ai/api/oauth/authorize`, token URL `https://contentmaschine.ai/api/oauth/token`)

Regenerate the masked area of an image already in your library from a prompt,
using GPT Image 2.5 Sunburst. Everything outside the masked area is preserved.
Returns a `job_id`; poll `GET /v1/jobs/{id}` until `completed`. There is no
region-edit status route.

Supply exactly one mask, never both: `mask_file_uuid` (a PNG already in your
library) or `mask` (inline base64 PNG bytes). Neither is a 400, and both is a 400.
The mask must match the source image's pixel dimensions exactly and must have an
alpha channel: fully transparent pixels (alpha 0) mark the area to change, opaque
pixels (alpha 255) mark the area to keep. The mask file must be smaller than
4194304 bytes (4 MB); an inline `mask` whose base64 payload is longer than 5592408 characters is refused before it is decoded.
The inline form exists because `files/upload` is not exposed as an MCP tool, so
inline is the only way an agent can supply a freshly drawn mask.

Every mask check runs before any credit is reserved: a refused mask costs nothing.
A request that passes is charged the current `image_region_edit` price, reported
as `estimated_credits` in the 202.

## Request body

- object
  - `source_file_uuid` string, uuid, required: UUID of the image in your library to edit.
  - `prompt` string, required: What to put inside the masked area.
  - `mask_file_uuid` string, uuid: UUID of a mask PNG already in your library. Send this OR `mask`, never both. Same pixel dimensions as the source, with an alpha channel: transparent = change, opaque = keep.
  - `mask` string: The mask PNG inline, as unwrapped base64 (an optional "data:image/png;base64," prefix is accepted). Send this OR `mask_file_uuid`, never both. Smaller than 4194304 bytes decoded; a payload longer than 5592408 base64 characters (prefix excluded) is refused before decoding. Same pixel dimensions as the source, with an alpha channel: transparent = change, opaque = keep.

## Response `202`

Region edit job queued

- JobQueued
  - `success` boolean
  - `data` object
    - `job_id` integer
    - `generation_id` integer
    - `generation_uuid` string, uuid
    - `status` string
    - `estimated_credits` number, float
  - `timestamp` string, date-time

## Other responses

- `400`: Validation error: a missing or malformed field, neither or both mask forms, or a mask that is not an alpha PNG, is too large, or does not match the source image's dimensions
- `401`: Missing or invalid API key
- `402`: Insufficient credits
- `403`: The source image or the mask file is not yours, or the API key lacks images:write
- `404`: Source image or mask file not found
- `422`: The job could not be queued
- `default`: Any other error. Every failure this API emits uses the same envelope; branch on `error.type`, never on `error.message`, and quote `error.correlation_id` to support.

---

[API](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api.md) · [All operations](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/contentmaschine/apis/contentmaschine-ai-api/revisions/28c74f46051c?raw)
