Image Generations

POST/v1/images/generations

Minimum-discount routing: Prefix the path with a min{N} segment (e.g. /min30/v1/images/generations) to require marketplace seller offers to meet a minimum estimated buyer discount before routing. Buyer-owned providers are not covered. See Minimum-Discount Routing.

OpenAI-compatible image generation via the marketplace. One synchronous request returns the image(s); the marketplace routes to the cheapest healthy seller for the model and settles USDC to that seller.

The marketplace also supports image-to-image editing via POST /v1/images/edits — or this same endpoint when the body carries a source image. See Image-to-Image below.

Request

Auth: API key (Authorization: Bearer inf_***), or pay-per-request via x402 (PAYMENT-SIGNATURE) or MPP (Authorization: Payment ***). With no auth, the endpoint returns 402 advertising both x402 and MPP. See Buyer endpoints.

  • Name
    model
    Type
    string
    required
    Description
    Model ID, e.g. venice-z-image-turbo, seedream-4.5, venice-flux-2-pro, gpt-5.4-image-2. Query /v1/models for the live catalog
  • Name
    prompt
    Type
    string
    required
    Description
    Text prompt
  • Name
    n
    Type
    integer
    Description
    Number of images (1–10, default 1). Token-metered models served over the chat wire return a single image
  • Name
    size
    Type
    string
    Description
    e.g. 1024x1024. Drives per-megapixel billing and the per-token output estimate
  • Name
    resolution
    Type
    string
    Description
    1K, 2K, or 4K. Selects the pricing tier for resolution-tiered models; when omitted, the tier is derived from size
  • Name
    quality
    Type
    string
    Description
    e.g. low, medium, high. Drives the per-token output estimate where the provider doesn't report usage
  • Name
    response_format
    Type
    string
    Description
    b64_json or url (passed through to the provider)

Headers include X-Request-Id. With response_format=url, items are { "url": "https://..." }.

Response — 200 OK
json
{
  "created": 1713200000,
  "data": [
    { "b64_json": "iVBORw0KGgo..." }
  ]
}

Image-to-Image (editing)

POST/v1/images/edits

Edit an existing image with a text prompt. Send a JSON body with the source image(s) and an edit-capable model; the marketplace routes to the cheapest healthy seller that supports image input. You can also send an edit to POST /v1/images/generations — including a source image in the body runs the edit flow there too. The min{N} prefix works on both paths.

Auth: same as generations — API key, or pay-per-request via x402 / MPP.

  • Name
    model
    Type
    string
    required
    Description
    An edit-capable model, e.g. nano-banana-2-edit, qwen-image-2-edit, seedream-v4-edit, flux-2-max-edit (most carry an -edit suffix). Query /v1/models for the live catalog
  • Name
    prompt
    Type
    string
    required
    Description
    The edit instruction
  • Name
    image
    Type
    string
    Description
    Source image — an https:// URL or a data: URI (e.g. data:image/png;base64,...). image_url is accepted as an alias. URLs are passed to the provider as-is; the marketplace never fetches them
  • Name
    input_images
    Type
    array
    Description
    Multiple source images. The first entry is the base (start) image; the rest are reference layers. Each entry is an https/data: URI string, or an object { "url": "...", "role": "start" | "reference" }. Max 8 images per request

size, quality, resolution, and response_format apply as on generations. Bare base64 (without the data: prefix) and http:// URLs are rejected.

Masked edits (inpaint) are not supported yet — sending a mask/mask_url returns 400 mask_not_supported.

Response: the standard image response (above). The default b64_json returns the edited image inline; response_format: "url" returns short-lived download URLs instead. Editing is synchronous and returns one edited image per request.

Single-image edit
bash
curl https://api.surplusintelligence.ai/v1/images/edits \
  -H "Authorization: Bearer inf_***" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-2-edit",
    "prompt": "make the sky a dramatic sunset",
    "image": "https://example.com/skyline.png"
  }'
Multi-image edit (base + reference)
json
{
  "model": "qwen-image-2-edit",
  "prompt": "apply the style of the second image to the first",
  "input_images": [
    { "url": "https://example.com/photo.jpg", "role": "start" },
    { "url": "https://example.com/style.jpg", "role": "reference" }
  ]
}

Pricing — canonical price × discount

Each image model has a canonical reference price (OpenRouter-first, then Venice, then the SI registry). A seller's offer is a discount off that canonical, and the marketplace routes to the deepest discount. You always pay the canonical × the winning offer's discount — never an arbitrary per-seller price.

Canonical follows the model's native metering unit:

UnitModels (examples)CanonicalBuyer charge
per-tokenNano Banana, GPT-image, Gemini image$/1M input + outputusage_tokens × canonical/1M × discount
per-imageZ-Image, SDXL, Seedream, Lustify, …$/imagecanonical/image × n × discount
per-megapixelFLUX.2 Pro/Max/Flex, Grok Imagine$/MPcanonical/MP × (w×h/1e6 × n) × discount
  • Per-token models bill on actual usage the provider reports; when a provider returns none (e.g. Venice serving a token-canonical model), usage is derived from size/quality so the buyer sees true per-1M pricing and the seller isn't underpaid.
  • Per-image and per-megapixel are deterministic from the request (n, size) — no provider usage needed.
  • Image-to-image bills the same way — the model's canonical price × the winning discount, per edited image (an edit returns one image). For models with resolution-tiered pricing, the rate follows the output resolution (resolution, or derived from size).
  • See the live canonical and effective discounts at /api/markets/:model and /v1/prices: token-image models show $/1M input/output, diffusion models $/image, FLUX/Grok $/MP.

All costs are USDC microdollars (1 USD = 1,000,000 microdollars). One settle() transaction pulls USDC from the buyer to the seller per completed request.

Errors

StatusMeaning
400Invalid request (bad JSON, validation, unknown model). Image-to-image adds: too_many_input_images (more than 8), invalid_image_input (a source that isn't an https URL or data: URI), image_required (an edit request with no usable image), mask_not_supported (inpaint is not supported yet)
402Insufficient USDC balance/allowance (API key), or payment required (no auth — dual x402/MPP challenge)
404No available sellers for the model
5xxProvider error (sanitized; the marketplace retries the next healthy seller before failing)