BlockRun

Image Editing API (img2img)

Edit existing images — pass one or more source images and describe what to change.

Two request formats are accepted
  • application/jsonimage as a data:image/...;base64,… string, or a JSON array of them for multi-image fusion. (BlockRun-native.)
  • multipart/form-data — OpenAI's format: repeated image[]=@file fields (plus mask, model, prompt, size, n). Files are converted internally.

Payment is always x402 (the X-Payment / PAYMENT-SIGNATURE header), regardless of body format. So you can send an OpenAI-shaped multipart body, but you still attach an x402 payment — the OpenAI SDK's native Bearer-key auth does not settle payment here. Use the BlockRun SDK / ClawRouter (which handle x402), or send either body format with your own x402 header.

Endpoint

NetworkURL
Basehttps://blockrun.ai/api/v1/images/image2image
Solanahttps://sol.blockrun.ai/api/v1/images/image2image
POST https://blockrun.ai/api/v1/images/image2image       # Base
POST https://sol.blockrun.ai/api/v1/images/image2image    # Solana

Request

{
  "model": "openai/gpt-image-1",
  "prompt": "change the background to a starry sky",
  "image": "data:image/png;base64,<base64-data>",
  "mask": "data:image/png;base64,<base64-data>",
  "size": "1024x1024",
  "n": 1
}

Parameters

ParameterTypeRequiredDescription
modelstringNoModel to use (default: openai/gpt-image-2). Supported: openai/gpt-image-1, openai/gpt-image-2, google/nano-banana, google/nano-banana-pro
promptstringYesDescription of edits to make
imagestring | string[]YesSource image as a base64 data URI, or an array of data URIs to fuse multiple sources into one variant (e.g. a reference image + a brand logo). OpenAI-compatible image[]. Max 4 images for OpenAI, 3 for Google.
maskstringNoMask image as base64 data URI (white = area to edit). Single-image only — cannot be combined with a multi-image image[] array.
sizestringNoOutput size (default: 1024x1024)
nintegerNoNumber of images to generate (default: 1)

Supported Models

Model IDProviderMaskSizesPricing
openai/gpt-image-1OpenAI1024x1024, 1536x1024, 1024x1536$0.02-0.04
openai/gpt-image-2OpenAI1024x1024, 1536x1024, 1024x1536$0.06-0.12
google/nano-bananaGoogle (Gemini 2.5 Flash Image)❌ prompt-only1024x1024$0.05
google/nano-banana-proGoogle (Gemini 3 Pro Image)❌ prompt-only1024x1024, 2048x2048, 4096x4096$0.10-0.15

Hybrid sync/async flow & settlement

Like /v1/images/generations, this endpoint is hybrid — it is not always synchronous:

  • Fast edits (≤30s inline window): 200 with the standard { created, data: [...] } body below. Payment settles inside this response.
  • Slow edits (>30s — multi-image gpt-image-2 fusion routinely takes longer): 202 with an async job envelope { id, status, poll_url, price, payment_status: "verified" }. Nothing has been charged yet. Poll GET {poll_url} (it lives under /v1/images/generations/{id} — edits share the same job store) with an x-payment header from the same wallet every 2–5s. USDC settles exactly once, on the first poll that observes status: "completed". A job that ends failed, or that you never poll, is never charged.
No charge until the image is ready

On the slow async path nothing is debited at submit time (payment_status: "verified"). USDC settles exactly once — on the first poll that sees status: "completed". Failed jobs and never-polled jobs are never charged.

The envelope fields, poll responses, status enum (queued → in_progress → completed | failed) and settlement guarantees are identical to image generation — see the full spec there. Go SDK blockrun-llm-go ≥ v0.17.0 (ImageClient.Edit) handles the hybrid flow transparently and always returns the synchronous shape.

Response

{
  "created": 1706000000,
  "data": [
    {
      "url": "https://...",
      "revised_prompt": "A photo with the background changed to..."
    }
  ],
  "price": { "amount": "0.063000", "currency": "USD" },
  "payment": { "status": "settled", "tx_hash": "0x…", "network": "base" }
}

Response Fields

FieldTypeDescription
createdintegerUnix timestamp
dataarrayArray of edited images
data[].urlstringURL to edited image
data[].revised_promptstringExpanded prompt
price.amountstringUSD charged for this call
payment.statusstringsettled | already_settled
payment.tx_hashstringOn-chain USDC settlement tx (also in X-Payment-Receipt header)

Examples

Via ClawRouter (recommended)

The easiest way is using ClawRouter's /img2img slash command, which reads local files automatically:

/img2img --image ~/photo.png change the background to a starry sky
/img2img --image ./cat.jpg --mask ./mask.png remove the background
/img2img --image /tmp/portrait.png --size 1536x1024 add a hat

Via ClawRouter API

ClawRouter handles x402 payments automatically:

# First, convert your image to base64
IMAGE_B64=$(base64 -i ~/photo.png)

curl -X POST http://localhost:8402/v1/images/image2image \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"openai/gpt-image-1\",
    \"prompt\": \"change the background to a starry sky\",
    \"image\": \"data:image/png;base64,${IMAGE_B64}\",
    \"size\": \"1024x1024\"
  }"

Direct API (cURL)

IMAGE_B64=$(base64 -i ~/photo.png)

# Base
curl -X POST https://blockrun.ai/api/v1/images/image2image \
  -H "Content-Type: application/json" \
  -H "X-Payment: $PAYMENT_HEADER" \
  -d "{
    \"model\": \"openai/gpt-image-1\",
    \"prompt\": \"change the background to a starry sky\",
    \"image\": \"data:image/png;base64,${IMAGE_B64}\",
    \"size\": \"1024x1024\"
  }"

# Solana
curl -X POST https://sol.blockrun.ai/api/v1/images/image2image \
  -H "Content-Type: application/json" \
  -H "X-Payment: $PAYMENT_HEADER" \
  -d "{
    \"model\": \"openai/gpt-image-1\",
    \"prompt\": \"change the background to a starry sky\",
    \"image\": \"data:image/png;base64,${IMAGE_B64}\",
    \"size\": \"1024x1024\"
  }"

Mask Usage

Mask is OpenAI-only

Masks apply to openai/gpt-image-1 and openai/gpt-image-2. Google nano-banana / nano-banana-pro are prompt-only — passing a mask to a Google model returns 400.

The mask defines which parts of the image to edit:

  • White pixels = areas to edit (AI generates new content here)
  • Black pixels = areas to keep unchanged

If no mask is provided, the AI will edit the entire image based on the prompt.

Multi-image input (image fusion)

Pass an array of source images in image to fuse several inputs into one result — e.g. a reference image + a brand logo, composed by a single prompt.

  • OpenAI gpt-image-1 / gpt-image-2: up to 4 source images.
  • Google nano-banana / nano-banana-pro: up to 3 source images (earlier images act as primary composition anchors).
  • mask cannot be combined with a multi-image array (mask is single-region only) → 400.
  • Exceeding a provider's image cap → 400.
Two ways to send multiple images
  • JSON (shown below): image as a JSON array of base64 data URIs.
  • Multipart (OpenAI's format): repeated image[]=@file fields, e.g. -F "image[]=@ref.png" -F "image[]=@logo.png".

Both are accepted. Payment is still x402 in either case (see the format note at the top).

REF_B64=$(base64 -i ~/reference-post.png)
LOGO_B64=$(base64 -i ~/brand-logo.png)

curl -X POST https://blockrun.ai/api/v1/images/image2image \
  -H "Content-Type: application/json" \
  -H "X-Payment: $PAYMENT_HEADER" \
  -d "{
    \"model\": \"google/nano-banana\",
    \"prompt\": \"place the brand logo in the corner, vintage warm palette, no text overlay\",
    \"image\": [
      \"data:image/png;base64,${REF_B64}\",
      \"data:image/png;base64,${LOGO_B64}\"
    ],
    \"size\": \"1024x1024\"
  }"

Same request in OpenAI multipart format (repeated image[]):

curl -X POST https://blockrun.ai/api/v1/images/image2image \
  -H "X-Payment: $PAYMENT_HEADER" \
  -F "model=google/nano-banana" \
  -F "prompt=place the brand logo in the corner, vintage warm palette, no text overlay" \
  -F "image[]=@reference-post.png" \
  -F "image[]=@brand-logo.png" \
  -F "size=1024x1024"

Single-image requests are unchanged — image as a plain string (JSON) or a single image[]/image file (multipart) both work.

Pricing

Prices include 5% BlockRun margin:

ModelSizePrice
GPT Image 11024x1024$0.021
GPT Image 11536x1024$0.042
GPT Image 11024x1536$0.042
ChatGPT Images 2.01024x1024$0.063
ChatGPT Images 2.01536x1024$0.126
ChatGPT Images 2.01024x1536$0.126
Nano Banana1024x1024$0.0525
Nano Banana Pro1024x1024$0.105
Nano Banana Pro2048x2048$0.105
Nano Banana Pro4096x4096$0.1575

Error Codes

CodeDescription
400Invalid request (bad image format, unsupported model, invalid size)
402Payment required
429Rate limit exceeded
500Server error
504Image editing timed out

What's next?