Generate an image on one of seven models, paid with x402

Generates one image from a prompt on the model you pick, square to 21:9 and up to 4K where the model offers it. Each model sells its own aspect ratios and its own price setting (resolution or quality); GET this path with no parameters for every option and price, and read the amount off the 402 challenge. A setting the model does not honour is refused with a 400 rather than silently dropped. Pay via the x402 protocol (HTTP 402): call without payment to receive a 402 challenge carrying the price and networks, sign the payment with an x402-capable wallet, and retry with the payment-signature header. The challenge lists two ways to pay the same amount: USDC on Base (eip155:8453) first, then USDC on Solana mainnet (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp); a client pays the first one it has a wallet for, and neither needs gas money in the paying wallet. No account, API key, or signup is involved, so the payment is the only credential. A payment presented again after it was redeemed is refused with a 409 (code PAYMENT_ALREADY_REDEEMED). Only the documented fields are read; a request carrying any other field is refused with a 400 before any payment moves.

The paid call answers 200 at once, with the statusUrl in the X-Status-Url header, then sends a whitespace byte every 2 seconds while it waits (JSON parsers ignore it), and ends with one complete JSON object. Read status in that body: success carries image, the URL of the image; error means it failed, nothing was charged for it, and retryUrl tries again on the wallet balance the payment left, without paying twice; running means it outlasted the wait (45 seconds by default, Prefer: wait=N for up to 720), so poll statusUrl. Send "async": true or Prefer: respond-async for an immediate answer (200, status running) with a statusUrl. Lost the statusUrl? GET /api/x402/purchases and sign its challenge with the paying wallet (Sign-In-With-X, free) to list every purchase with its file and a fresh statusUrl. And the same request sent again from the same wallet, once the first render has finished and its file never reached you, is answered with that file (alreadyPaid, paidUsd 0) and the new payment is not taken.

post/api/x402/image

Request

  • Base URL: https://www.trezalabs.com
  • URL: https://www.trezalabs.com/api/x402/image
  • Auth: HTTP bearer

Headers

Preferstring

Optional. respond-async answers at once (200, status running) with a statusUrl to poll, like "async": true. wait=N sets how long the call waits, in seconds (default 45, at most 720), before it ends with status running and the statusUrl. Echoed in Preference-Applied.

Request body

promptstring required

What the image should show.

model'nano-banana' | 'nano-banana-2' | 'nano-banana-pro' | 'gpt-image-2' | 'seedream-5-pro' | 'flux-2-pro' | 'recraft-v4.1'

nano-banana (Google Nano Banana (Gemini 2.5 Flash Image)): Fast, cheap and good at following a prompt. The default. nano-banana-2 (Google Nano Banana 2 (Gemini 3.1 Flash Image)): Sharper than Nano Banana, with a resolution choice up to 4K. nano-banana-pro (Google Nano Banana Pro (Gemini 3 Pro Image)): Google's best image model: legible text in the image, complex scenes, up to 4K. gpt-image-2 (OpenAI GPT Image 2): OpenAI image generation with a quality choice; strong at text and layout. seedream-5-pro (ByteDance Seedream 5.0 Pro): Photoreal detail at 2K by default, or 1K for less. flux-2-pro (Black Forest Labs FLUX.2 Pro): Crisp, photographic FLUX output. Square is the cheapest shape. recraft-v4.1 (Recraft V4.1): Design-minded: illustration, brand graphics and clean compositions.

aspectRatio'1:1' | '16:9' | '9:16' | '4:3' | '3:4' | '3:2' | '2:3' | '4:5' | '5:4' | '21:9'

nano-banana: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9. nano-banana-2: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9. nano-banana-pro: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9. gpt-image-2: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 21:9. seedream-5-pro: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9. flux-2-pro: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 21:9. recraft-v4.1: 1:1, 16:9, 9:16, 4:3, 3:4.

resolution'512' | '1K' | '2K' | '4K'

nano-banana-2: 1K, 512, 2K, 4K (default 1K). nano-banana-pro: 1K, 2K, 4K (default 1K). seedream-5-pro: 2K, 1K (default 2K). Refused on the other models.

quality'low' | 'medium' | 'high'

gpt-image-2 only: low, medium (default) or high. Refused on the other models.

asyncboolean

true answers at once (200, status running) with a statusUrl to poll.

Response

Payment settled and the response waited for the image. Streamed: the status and headers are sent at once (X-Status-Url carries the statusUrl), then a whitespace byte every 2 seconds, then one complete JSON object. The HTTP status is 200 whatever happened, so read status in the body.

runIdstring
status'success' | 'error' | 'partial' | 'cancelled' | 'running'

success carries image. error, partial, and cancelled carry the failure fields. running means it is still going; poll statusUrl.

startedAtstring date-time
finishedAtstring date-time
durationMsinteger
imagestring uri

URL of the finished image. Use it exactly as given: its query parameters, including c=, are part of it.

statusUrlstring uri

The run's status, now and later. It carries its own signed claim ticket, so it needs no other credential. Use it exactly as given: the runId contains '#', encoded as %23.

pollAfterMsinteger

Only when status is running: how long to wait before polling statusUrl.

paidUsdnumber

What this request cost.

modelstring
aspectRatiostring
resolutionstring
qualitystring
networkstring

Where the payment settled: eip155:8453 (Base) or solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp (Solana).

transactionstring

The settled payment: a 0x transaction hash on Base, a base58 transaction signature on Solana.

payerstring

The paying wallet.

errorstring

Failed runs only. What went wrong, in the provider's words.

reason'prompt_refused' | 'render_failed'

Failed runs only. prompt_refused: the model declined the prompt, so reword it. render_failed: it did not finish; the same prompt may succeed.

retryableboolean

Failed runs only. True until the run's one free retry has been used.

retryUrlstring uri

Failed runs only. POST here to try again on the wallet balance, optionally with {"prompt": "..."} in the body. Carries the same signed ticket.

messagestring

Failed runs only. What happened and what to do, in one sentence.

balanceUsdnumber

Failed runs only. The wallet balance the retry spends.

Example response

{
  "status": "success"
}

Changes

No recorded changes to this operation across all 1 revision of this API.