---
title: "Generate an image"
method: POST
path: "/v1/generations"
tags: ["Generations"]
---

# Generate an image

`POST /v1/generations`

## Request

- Base URL: `https://nanostudiopro.com/api`
- URL: `https://nanostudiopro.com/api/v1/generations`
- Auth: HTTP bearer

The endpoint you're here for. Sends your prompt to the model and returns the resulting image.

### Two ways to call it

- **JSON** — text-only prompts. Send `Content-Type: application/json` with a body containing `project_id` and `prompt`. Optionally reference existing assets by ID.
- **Multipart** — attach reference images directly. Send `Content-Type: multipart/form-data` with one or more `reference_file[]` parts. Up to **14 references per generation** (combined files + asset IDs). Files attached this way are also saved to your asset library under category `upload` so you can reuse them later — the IDs come back in the response as `saved_asset_ids`.

### Aspect ratio and resolution

`aspect_ratio` controls the shape (`1:1`, `4:5`, `9:16`, `16:9`, etc.); `resolution` controls pixel density (`1K`, `2K`, `4K`). Defaults: `4:5` shape, `1K` resolution. The model is instructed to honor the picked ratio in addition to whatever you write in the prompt.

### Cost

Charged in **credits**, by model and resolution. Nano Banana 2.1 bills the `generate_*` rows below; Nano Banana Pro bills `generate_pro_*` and GPT Image 2.5 (both variants, one price) bills `generate_gpt_*` — read them from `GET /v1/pricing`.

| Resolution | Credits |
|------------|---------|
| 1K         | 60     |
| 2K         | 85     |
| 4K         | 170     |

References don't add cost. Failed calls don't deduct (the credit deduction runs only after the model returns and the row is saved).

### Naming

Pass `name` to label the generation in your library (e.g. `"Hero shot — linen suit"`). If you don't, we'll auto-derive a short name from your prompt.

## Request body

- object
  - `project_id` string, required
  - `prompt` string, required
  - `name` string: Optional human-friendly name.
  - `aspect_ratio` '1:1' | '4:5' | '3:4' | '9:16' | '16:9' | '3:2' | '2:3'
  - `resolution` '1K' | '2K' | '4K'
  - `model` 'gemini-nano-banana-2.1' | 'gemini-3-pro-image' | 'gpt-image-2.5-flare' | 'gpt-image-2.5-sunburst': Which model renders it. Nano Banana 2.1 (`gemini-nano-banana-2.1`, default): light, texture, mood, the fastest. Nano Banana Pro (`gemini-3-pro-image`): holds structure and proportion exactly. GPT Image 2.5 Flare (`gpt-image-2.5-flare`): text you can actually read — labels, packaging, signs. GPT Image 2.5 Sunburst (`gpt-image-2.5-sunburst`): the same, more careful with references, slower. Names work too: `nano-banana-2`, `nano-banana-pro`, `gpt-2.5-flare`, `gpt-2.5-sunburst`. GPT renders 1K and 2K only — asking it for 4K is a `400`.
  - `reference_asset_id` string[]: Reuse existing asset IDs as references (max 14 total).
  - `entity_ids` string[]: Saved characters, props or places (ids from `GET /v1/entities`) whose baked reference sheet to attach. Writing `@slug` in the prompt does the same — a look is `@parent/look` or its own slug — and the prompt is rewritten so the model knows which picture is whom. Sheets go after your own references, within the model's reference limit; the response's `entities` says which went in and which were dropped. Unknown `@words` are left as typed. To leave something out, write `-@slug` (that prop comes off every items sheet the request sends, and the words are removed from the prompt) or pass `-<id>` here; `@slug/alone` or `<id>/alone` sends the entity without its items sheet. The response's `entities.excluded` lists what was left out.

## Response `201`

Generation created

- GenerationCreated: A stored generation as returned in list responses.
  - `id` string
  - `project_id` string
  - `name` string, nullable
  - `metadata` object, nullable: The fields you sent as `metadata` when uploading or importing it, returned unchanged.
  - `image_url` string, uri: Signed URL to the generated image. Tied to a ~6-hour signing window (always at least 10 minutes of validity left); re-fetch the resource for a fresh one.
  - `prompt_used` string: The full prompt sent to the model — includes the aspect/resolution directive we append.
  - `aspect_ratio` '1:1' | '4:5' | '3:4' | '9:16' | '16:9' | '3:2' | '2:3'
  - `resolution` '1K' | '2K' | '4K'
  - `width` integer, nullable: Real width in pixels (if measured).
  - `height` integer, nullable
  - `created_at` string, date-time
  - `credits_remaining` integer: User's credit balance after this call.
  - `model` string: The model that rendered it — the request's `model`, or the default.
  - `reference_count` integer: How many reference images were used.
  - `saved_asset_ids` string[]: IDs of any reference files attached via multipart that were persisted to your asset library.
  - `task_id` string: ID of the Task row tracking this generation. Pass to `GET /v1/tasks/{id}` to poll lifecycle status. The Task is already `complete` by the time you receive this response (the call is synchronous), but the id is useful for cross-referencing in logs, audit trails, or batch dashboards.

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid token
- `402`: Not enough credits
- `404`: Project or referenced asset not found
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api.md) · [All operations](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nanostudiopro/apis/nano-studio-pro-api/revisions/b454211e598e?raw)
