---
title: "Make a sheet of elements (credits)"
method: POST
path: "/v1/sheets"
tags: ["Sheets"]
---

# Make a sheet of elements (credits)

`POST /v1/sheets`

## Request

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

Makes one sheet, server-side. Name the kind, then what goes on it: `sequences` by id from `/v1/sheets/options` (each `{family, type, id, level}`; `smooth` puts an in-between after every drawing and is the default), or `items` as plain descriptions, or both — sequences first, then items. For animation add `subject` (who is in every frame) and `art_style` (`photograph`, `film-still`, `studio-portrait`, `render-3d`, `stop-motion` for a real subject; `inked-cel`, `anime-cel`, `watercolour`… for a drawn one). Pixel sprites take no style: pixel art is the style.

The server plans the grid (columns, rows, sheet shape, resolution) from the kind and the count, writes the prompt that makes sheets come back cuttable, and records the recipe — including the sequences, so the sheet's atlas carries one animation tag each. **Never write this prompt yourself and never send it to `/v1/generations`.**

### Cost

One image at the planned tier: the `generate_*` rows of `GET /v1/pricing` for the chosen model (GPT Image reaches 2K only; the planner allows for it). The response carries `credits_cost` and `pricing_key`.

**Quote first.** `dry_run: true` runs every check and the planner and answers `200` with `status: quote`, the plan, the prompt and the price; nothing is generated or charged. The same body without it answers `201` with the generation.

## Request body

- object
  - `project_id` string, required
  - `kind` 'icons' | 'stickers' | 'sprites' | 'frames' | 'props', required: `frames` = animation of one subject, real or drawn; `sprites` = 8/16-bit pixel art; the rest are matched sets.
  - `sequences` object[]: Animations from `/v1/sheets/options`, in order. Several stack on one sheet.
    - `family` string, required
    - `type` string, required
    - `id` string, required
    - `level` 'key' | 'full' | 'smooth'
  - `items` string[]: Plain elements, one short description each (max 200 chars, 100 a sheet). Required when there are no sequences.
  - `subject` string: Who or what is in every frame. Ordered kinds only.
  - `art_style` string: A style id from the options. `frames` only.
  - `style` string: Your own words about the look, joined after `art_style`.
  - `ground` 'black' | 'white' | 'green' | 'magenta': Pick the value NOT in the artwork.
  - `model` 'gemini-nano-banana-2.1' | 'gemini-3-pro-image' | 'gpt-image-2.5-flare' | 'gpt-image-2.5-sunburst'
  - `per_row` integer: Override the planned columns.
  - `resolution` '1K' | '2K' | '4K': Override the planned tier; pulled down to the model's ceiling.
  - `reference_ids` string[]: Sheets of the same thing to match; for `frames`, the subject to keep.
  - `style_ids` string[]: Pictures whose look to borrow.
  - `reference_note` string
  - `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. Here `@slug` is read in `subject` and `reference_note`, and the sheet joins `reference_ids` as a matched reference.
  - `dry_run` boolean

## Response `200`

`dry_run`: `status: quote` with `plan`, `sequences`, `prompt`, `credits_cost`, `pricing_key`

## Other responses

- `201`: The generation (id, image_url, …) plus `plan`, `sequences`, `prompt`, `credits_cost`, `pricing_key`, `task_id`
- `400`: validation_error — unknown kind, model, art_style or sequence (the message names what exists)
- `402`: insufficient_credits or token_cap_exceeded
- `404`: Project not found

---

[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/7f7d4a72b17c?raw)
