Inference Cheap

Image generation

Generate, edit, and stream images through the Inference Cheap API.

For agents — copy the image prompt.

Use https://openai.inference.cheap/v1 with a key that allows image generation.

Choose an interface

InterfaceUse it for
POST /v1/images/generationsA prompt that produces image results.
POST /v1/images/editsA prompt plus source images, optionally with a mask.
POST /v1/responses with an image_generation toolImage generation inside a conversation or tool workflow.

All three interfaces support streaming.

Generate an image

Install openai and set INFERENCE_CHEAP_API_KEY:

import base64
import os
from pathlib import Path
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["INFERENCE_CHEAP_API_KEY"],
    base_url="https://openai.inference.cheap/v1",
    timeout=300.0,
)

result = client.images.generate(
    model="gpt-image-2",
    prompt="A small red sailboat on a calm blue lake, watercolor illustration.",
    n=1,
    output_format="png",
)
Path("sailboat.png").write_bytes(base64.b64decode(result.data[0].b64_json))

gpt-image-2 is the default. Image access is separate from /v1/models.

Edit an image

For local files, use a multipart upload through the SDK:

with open("sailboat.png", "rb") as source:
    result = client.images.edit(
        model="gpt-image-2",
        image=source,
        prompt="Change the sail to yellow. Keep the boat and lake composition.",
        output_format="png",
    )

Path("sailboat-edited.png").write_bytes(
    base64.b64decode(result.data[0].b64_json)
)

JSON edits use images[].image_url (HTTPS or base64 data URL) and optional mask.image_url:

{
  "model": "gpt-image-2",
  "prompt": "Change the sail to yellow.",
  "images": [
    { "image_url": "data:image/png;base64,REPLACE_WITH_IMAGE_BASE64" }
  ]
}

Multipart fields: image / image[], optional mask. Images file_id inputs are unsupported. Masks do not guarantee pixel-perfect protection.

Parameters and output

Controls are forwarded to the model; supported values and limits vary.

ParameterCurrent behavior
promptRequired, non-empty.
modelDefaults to gpt-image-2; the requested image model is used for routing.
nPositive integer; defaults to 1. Multiple-image requests depend on the model's limits.
size, quality, backgroundForwarded to the image tool. Omit for automatic choices; handle unsupported-option errors.
output_formatRequest png, jpeg, or webp; match the saved file extension to the output format.
output_compressionForwarded when supplied, for formats that support compression.
moderationForwarded when supplied; do not assume it disables safety checks.
streamfalse returns a final JSON response; true returns SSE events.
partial_imagesRequests streamed previews; previews are optional and are not final outputs.
response_formatOmit for data[].b64_json. url returns inline data: URLs on the current subscription-backed adapter, not hosted download links.
input_fidelityDoes not control the current subscription-backed Images adapter; omit it.

Decode data[].b64_json; response_format: "url" returns inline data: URLs. Image requests can take minutes. Allow a suitable timeout, parse the final JSON or stream outcome, and handle errors even after HTTP 200. For 413, reduce the payload.

Stream images

Set stream: true on the Images request and use an SDK or SSE reader. Generation events include image_generation.partial_image and image_generation.completed; edits use the image_edit prefix. Handle error events and only save a completed result as the final image.

Use the Responses image tool

Use a text model with image-tool access and specify the image model in the tool:

response = client.responses.create(
    model="gpt-5.6-sol",
    input="Draw a watercolor red sailboat on a calm blue lake.",
    tools=[{"type": "image_generation", "model": "gpt-image-2"}],
    tool_choice={"type": "image_generation"},
)

images = [item for item in response.output if item.type == "image_generation_call"]
if not images:
    raise RuntimeError("The response did not contain a completed image.")
Path("sailboat.png").write_bytes(base64.b64decode(images[0].result))

Use action: "edit" with image input for edits. The Responses mask field is input_image_mask: { image_url: "..." } inside the tool, unlike the Images endpoint's mask field. Standard Responses streaming also delivers image-tool progress and partial images when available.

For the underlying schemas, see OpenAI's Images API and Responses image tool. Apply the Inference Cheap differences documented on this page.

For agents

Copy this Markdown prompt to your agent.

Generate or edit images
# Use Inference Cheap images

- Base URL: https://openai.inference.cheap/v1. Read INFERENCE_CHEAP_API_KEY
  from the project's secret store; never log it. The key needs image access.
- Use Images for standalone requests; Responses for conversation workflows.
  Image model: gpt-image-2. Responses also needs an available text model.
- Start with n=1. Add options only as needed; allow several minutes per request.
- For edits, use the user's source image: multipart image/image[] or JSON
  images: [{ image_url: "..." }]. Images file_id inputs are unsupported.
- Decode b64_json or inline data: URLs. Save with the matching extension.
  Check the final result; previews and HTTP 200 alone do not mean completion.
- Show the output and report failures. Do not blindly repeat timed-out requests.
- Examples and options: https://docs.inference.cheap/images

On this page