
# AI Generation Pricing

Generation is paid for in credits, from the same balance as rendering. Each generation is priced at what the model's
provider charges for that request, plus a small margin, converted to credits. Generation is here so you can use these
models without a separate provider account or integration, and its price stays close to the provider's own.

## Get a quote

`POST /generate/quote` takes the same body as the [generate endpoint](/docs/guide/generating-assets/generative-ai#the-generate-endpoint)
and returns what that generation would cost. Nothing is generated, reserved or charged.

```bash
curl -X POST \
     -H "Content-Type: application/json" \
     -H "x-api-key: $SHOTSTACK_API_KEY" \
     -d '{"asset": {"type": "video", "prompt": "Waves rolling onto a black sand beach", "model": "seedance-2.0-text-to-video", "options": {"resolution": "720p"}}, "length": 8}' \
     https://api.shotstack.io/edit/stage/generate/quote
```

```json
{
    "credits": 15.1696,
    "ceiling": false
}
```

To price a clip in an edit, send its asset and its numeric `length`.

`ceiling` is `true` when the request has no `length` for a model that is charged by length. The quote is then an
[estimate](#when-a-quote-is-an-estimate).

A quote is worked out when you ask for it. It doesn't hold credits, and prices follow the providers' prices, so ask again
rather than storing one.

## What each model's price depends on

| Model | Charged per | Price changes with |
| --- | --- | --- |
| `nano-banana-2`, `nano-banana-2-edit` | Image | `resolution`: 0.5K, 1K (default), 2K, 4K |
| `nano-banana-pro` | Image | `resolution`: 1K (default), 2K, 4K |
| `gpt-image-2.5-sunburst` | Image | `resolution`: 1K (default), 2K, 4K |
| `gpt-image-2.5-sunburst-edit` | Image, plus each reference image | `resolution`: 1K (default), 2K, 4K |
| `flux-schnell` | Image | Fixed price |
| `seedance-2.0-text-to-video`, `seedance-2.0-image-to-video` | Second of video, 4 to 15 | `resolution`: 480p, 720p (default), 1080p |
| `seedance-2.5-text-to-video`, `seedance-2.5-image-to-video` | Second of video, 4 to 30 | `resolution`: 480p, 720p (default), 1080p |
| `wan-3.0-prime-text-to-video`, `wan-3.0-prime-image-to-video` | Second of video, 2 to 30 | `resolution`: 480p, 720p, 1080p (default) |
| `gemini-omni-flash-1.1-text-to-video`, `gemini-omni-flash-1.1-image-to-video` | Second of video, 3 to 10 | `resolution`: 360p, 720p (default), 1080p, 4k |
| `elevenlabs-multilingual-v2`, `elevenlabs-turbo-v2.5`, `minimax-speech-2.8-hd` | Character of the prompt | Fixed rate |
| `polly-neural` | Character of the prompt, minimum 100 | Fixed rate |
| `elevenlabs-music` | Started minute of music, up to 10 minutes | Fixed rate |

Video is charged per whole second, rounded up. A length outside a model's range is generated and charged at the nearest
end of it: a 2-second Seedance clip is a 4-second generation.

Music is charged per started minute, so a 30-second track and a 60-second track cost the same, and a 61-second track
costs two minutes.

### When a quote is an estimate

For video and music, a quote is exact when the length is known up front: a clip with a numeric `length`, or a request
with `length`. It is a best estimate when the length isn't known until the asset is generated:

- The clip uses a [smart clip](/docs/guide/architecting-an-application/smart-clips) length, `"auto"` or `"end"`.
- The request has no `length`.
- The asset depends on another clip through an [alias](/docs/guide/architecting-an-application/aliases).

The estimate assumes the model's default length. The final charge follows the actual length of the generated asset, so
it can be higher or lower than the quote.

| Model | Default length |
| --- | --- |
| Seedance 2.0 and 2.5 | 15 seconds |
| Wan 3.0 Prime | 5 seconds |
| Gemini Omni Flash 1.1 | 8 seconds |
| ElevenLabs Music | 30 seconds |

## When generation is free

- **It was generated before.** An asset identical to one already stored costs nothing. See
  [reusing earlier generations](/docs/guide/generating-assets/generative-ai#reusing-earlier-generations) for what counts
  as identical. In a render, this applies to assets stored before the render starts.
- **The generation failed.** A failed generation isn't charged. If a render fails after some of its assets were
  generated, those assets are charged and kept, and rendering again reuses them at no charge.
- **The asset has no prompt.** An asset with only a `src` is never generated.

## The sandbox

Generation in the sandbox is charged like production, from your production credit balance. Sandbox renders stay free and
watermarked, but the assets they generate are not. The two environments store generations separately, so an asset made in
the sandbox is charged again the first time production generates it.

## Seeing what you were charged

In production, a render's status response includes `credits`, the total for rendering and generation together. The
sandbox omits it. Your credit usage is in the [dashboard](https://dashboard.shotstack.io).

## Access

AI generation needs a plan that includes it. If yours doesn't, generation requests return `403` with a `code` saying why,
and `GET /models` marks each model `"available": false` with an `unavailableReason`.

| Response | Meaning |
| --- | --- |
| `402` | Your balance is too low for this generation. `available` shows your balance. |
| `403` | Your plan doesn't include this generation, or AI generation is turned off for the account. |
| `503` | Access or billing couldn't be checked. Retry after the `Retry-After` header. |

A render that runs out of credits while generating fails with the reason in its error.
