Image Editing

POST /v1/images/edits

Edit an existing image with the OpenAI-compatible images endpoint. Only the two GPT Image models support editing (gpt-image-2 and gpt-image-1.5); the FLUX models do not. See Models & Pricing for the full price tables.

Requests are multipart/form-data, non-streaming: one POST, one JSON response.

curl https://api.singularityapi.dev/v1/images/edits \
-H "Authorization: Bearer $SINGULARITY_API_KEY" \
-F "model=gpt-image-2" \
-F "image[]=@photo.png" \
-F "mask=@mask.png" \
-F "prompt=Add a beach ball" \
-F "quality=low" \
-F "size=1024x1024"

Parameters

ParameterRule
modelrequired; gpt-image-2 or gpt-image-1.5
promptrequired, 1–32,000 characters
image / image[]required; 1–16 image files, each png, jpeg, or webp (use image[] for more than one file)
maskoptional; at most one file, must be png
n1–4 (each image billed at the grid price)
sizeauto, 1024x1024, 1024x1536, or 1536x1024; omitted/auto resolves to 1024x1024
qualityauto, low, medium, or high; omitted/auto resolves to high
backgroundauto, opaque, or transparent
useroptional string, 1–256 characters

Omitted size and quality (and the literal value "auto") resolve to 1024x1024 and high; the substitution is recorded in the request’s transformed_fields on its receipt.

stream is not supported on this endpoint (absent, or the literal false, is accepted; true is rejected).

Limits

  • Up to 16 image parts per request.
  • The whole request body (images included) is capped at 32 MiB.
  • n is capped at 4.
  • Image inputs must be png, jpeg, or webp; the mask, if present, must be png.
  • prompt is capped at 32,000 characters.

Rejected parameters

output_format, output_compression, moderation, response_format, partial_images, input_fidelity, and stream: true are not yet supported on this endpoint and are rejected with a 400 before any charge is reserved. input_fidelity is rejected on both models: a live test found gpt-image-2 rejects it upstream with its own 400 (invalid_input_fidelity_model), while gpt-image-1.5 accepts it — since a model-specific allowlist isn’t how request validation works here, it stays rejected for both until a per-model price ships.

Billing

An edit costs exactly what a generation of the same quality, size, and n costs — see Models & Pricing. Input images are not charged separately.

Response shape

{
"created": 1756600000,
"data": [
{ "b64_json": "..." }
],
"usage": { "input_tokens": 600, "output_tokens": 300, "total_tokens": 900 }
}

The response returns base64 image data in data[].b64_json. The provider’s usage block is informational only — image requests are billed deterministically at the admitted units, not by token usage. The exact charge for every request is on its receipt.