Protocols

Studio Unified

One asynchronous image API for 🎨 GPT Image and 🍌 Nano Banana.

Let AI read the docs πŸ₯ΊπŸ‘‰
Protocol navigation

Switch protocols here

Examples

One image per job. Results include both URL and Base64.

More parameters

The key stays in this browser and is used only for requests you send.

Need a key? Create oneChoose the 🎨 GPT Image group when creating your key.
ASYNC
$pip install httpx
import jsonimport httpximport timeapi_key = "YOUR_API_KEY"api_base = "https://api.1route.dev"payload = {    "model": "openai/gpt-image-2.5-flare",    "prompt": "Editorial portrait of a woman in profile beside a wind-bent tree, late afternoon light, deep cobalt coat, pale concrete wall, subtle film grain, restrained color palette, clean composition, vertical 4:5.",    "size": "auto"}headers = {"Authorization": f"Bearer {api_key}"}response = httpx.post(    api_base + "/api/v1/images/generations/jobs",    headers=headers,    json=payload,    timeout=1500,)response.raise_for_status()result = response.json()job_url = f"{api_base}/api/v1/images/jobs/{result['jobId']}"while result["phase"] in ("queued", "running"):    time.sleep(1.5)    snapshot = httpx.get(job_url, headers=headers, timeout=30)    snapshot.raise_for_status()    result = snapshot.json()if result["phase"] != "completed":    raise RuntimeError(result)response = httpx.get(f"{job_url}/result", headers=headers, timeout=120)response.raise_for_status()result = response.json()print(json.dumps(result, ensure_ascii=False, indent=2))
Response
No request sent

OpenAPI integration

When calling the Studio HTTP API directly, ask your AI to read this OpenAPI document or import it into a tool that supports OpenAPI to inspect endpoints, request fields, and response schemas. Use it with the Studio guide for model extensions and the asynchronous job workflow when generating integration code.

This OpenAPI 3.1 document describes Studio generation, editing, job status, results, cancellation, SSE, and media endpoints. After import, configure the Base URL and API key shown on this page, then submit a job, poll its status, and retrieve its result.

Request lifecycle

Submit generation / edit
    ↓ 202 with jobId
queued β†’ running β†’ completed β†’ retrieve result β†’ save image
             β”œβ†’ failed
             β””β†’ cancelled

One job generates one image. For bulk generation, submit separate jobs, store their IDs, and respect the key's concurrency allowance. 202 means the job was created, not that the image is ready.

Generate an image

POSThttps://api.1route.dev/api/v1/images/generations/jobs
Default https://api.1route.devFrequent timeouts? Use https://image-api.1route.dev

Use Authorization: Bearer YOUR_API_KEY and a JSON request body.

Need a key? Create oneChoose the 🎨 GPT Image or 🍌 Nano Banana group for your model.

🎨 GPT Image

{
  "model": "openai/gpt-image-2.5-flare",
  "prompt": "A product photograph of a white ceramic cup, pale gray background, soft side light",
  "size": "1024x1024",
  "quality": "high"
}

model requires the openai/ prefix. Options are gpt-image-2, gpt-image-2.5-flare, and gpt-image-2.5-sunburst; gpt-image-2.5 is a Flare alias.

prompt is a non-empty description. size defaults to auto and accepts 1K, 2K, 4K, or WIDTHxHEIGHT. Pixel dimensions are mapped to an upstream tier.

quality is a model extension. Image 2 accepts auto, low, medium, and high; 2.5 adds xhigh and max. Higher quality may take longer. 🎨 GPT Image requests do not use resolution or aspect_ratio.

🍌 Nano Banana

{
  "model": "google/gemini-3.1-flash-image",
  "prompt": "A spring menu poster for a coffee shop, title SPRING MENU",
  "resolution": "2K",
  "aspect_ratio": "3:4"
}

Use google/gemini-3.1-flash-image (🍌 Nano Banana 2) or google/gemini-3-pro-image (🍌 Nano Banana Pro). resolution defaults to 1K; common options are 1K, 2K, and 4K. aspect_ratio defaults to 1:1; common ratios include 3:2, 2:3, 4:3, 3:4, 16:9, and 9:16. Do not send size for Google models.

References and editing

POSThttps://api.1route.dev/api/v1/images/edits/jobs
Default https://api.1route.devFrequent timeouts? Use https://image-api.1route.dev
{
  "model": "openai/gpt-image-2.5-sunburst",
  "prompt": "Keep the cup's shape and logo. Change the background to a wooden table.",
  "size": "1024x1024",
  "images": [
    { "url": "https://your-image-host.example/product.png" },
    { "dataUrl": "data:image/png;base64,<image bytes>" }
  ]
}

images requires at least one item. Each item contains exactly one of url and dataUrl; the array can mix both and preserves order. The server downloads public URLs. Encode local files as complete Data URLs; Studio Unified does not accept multipart submissions.

For 🎨 GPT Image edits, an optional mask: { "image_url": "data:image/png;base64,..." } applies to the first reference. Transparent areas indicate the region to change. Describe the intended edit in the prompt as well.

Model-specific extensions

Other top-level fields are handled by the chosen native adapter. Examples include 🎨 GPT Image quality, output_format, output_compression, background, and moderation, and Google generationConfig, systemInstruction, and safetySettings.

Public prompt, images, and dimension fields own their corresponding content. For example:

{
  "model": "google/gemini-3-pro-image",
  "prompt": "A landscape exhibition poster with the words DESIGN WEEK",
  "resolution": "2K",
  "aspect_ratio": "16:9",
  "generationConfig": { "temperature": 0.7 }
}

Submission response

{
  "jobId": "job_example",
  "phase": "queued",
  "durationGuidance": { "tier": "2K", "timeoutSeconds": 150, "milestones": [] }
}

Use jobId for subsequent operations. phase is the current state. durationGuidance contains the tier, timeout, and waiting-time guidance. Milestone items are omitted in this example; each contains percentile, seconds, level, cardMessage, detailTitle, and detailBody. These describe expected waiting time, not completion percentage. Use the actual response's timeout.

Query the job

GEThttps://api.1route.dev/api/v1/images/jobs/{jobId}
Default https://api.1route.devFrequent timeouts? Use https://image-api.1route.dev

Use the same key as the submission. The main response fields are shown below:

{
  "jobId": "job_example",
  "model": "openai/gpt-image-2.5-flare",
  "hasInputImage": false,
  "phase": "running",
  "createdAt": 1788940800000,
  "updatedAt": 1788940802000,
  "startedAt": 1788940801000,
  "durationGuidance": { "tier": "2K", "timeoutSeconds": 150, "milestones": [] }
}
PhaseMeaningNext step
queuedQueued for executionPoll or subscribe
runningGeneratingWait or cancel
completedImage generatedRetrieve the result
failedJob failedRead error
cancelledJob cancelledStop polling

createdAt, updatedAt, startedAt, and finishedAt are Unix milliseconds. Optional fields may be omitted until available.

queuePosition is the queue position, and message describes progress. Use phase to determine the job's state. usage contains known usage and error contains failure details.

Retrieve and save the image

GEThttps://api.1route.dev/api/v1/images/jobs/{jobId}/result
Default https://api.1route.devFrequent timeouts? Use https://image-api.1route.dev
{
  "images": [{
    "url": "https://api.1route.dev/api/v1/images/files/media_example",
    "base64": "<complete image bytes>",
    "mimeType": "image/png"
  }],
  "usage": {}
}

Results include both url and base64. mimeType identifies the format. There is no public delivery-format switch in Studio Unified; read the field you need.

import base64
from pathlib import Path

image = result["images"][0]
Path("output.png").write_bytes(base64.b64decode(image["base64"]))

Images and stored results are retained for 72 hours, then cleaned up. Download them for long-term use. Media endpoints support GET and HEAD; expired content returns 410 result_expired.

SSE progress and cancellation

GET /api/v1/images/jobs/{jobId}/events returns text/event-stream. Event names match phases such as running and completed; data contains a snapshot. heartbeat events contain {}. The connection ends after a terminal phase.

event: running
data: {"jobId":"job_example","phase":"running",...}

event: heartbeat
data: {}

DELETE /api/v1/images/jobs/{jobId} requests cancellation and returns a snapshot. A job that has already finished may still return completed; inspect the returned phase. Closing a browser wait or SSE connection does not cancel the job.

Idempotency and errors

Submissions accept Idempotency-Key. The same API key, idempotency value, and request return the original job; a different request with the same idempotency value returns 409.

HTTP errors contain error.status, message, type, code, and param. Generation failures after acceptance appear in the job snapshot's error.

HTTP statusCommon cause
400Invalid model prefix, dimensions, reference, or fields
401Missing or invalid key
404Job not found or owned by another key
409Idempotency conflict, unfinished or cancelled result
410Expired image or result
413Request exceeds the body limit
415Submission is not application/json
429Quota or concurrency; inspect the error
500 / 502 / 504Job, media, upstream, or timeout error

Request bodies are limited to 512 MiB and each input media file to 80 MiB; model-level limits also apply. For frequent timeouts, use the alternate address shown on this page.