---
title: Why Nolgia
description: One API and one job model for image, video, audio and 3D, a price you see before you spend, and explicit refund outcomes for failed renders.
---

# Why Nolgia

You can generate image, video, audio and 3D media through the same API, quote a request before spending credits, and reuse your subjects and looks across generations.

## One API, one job model

`POST /generate/image`, `POST /generate/video`, `POST /generate/audio` and `POST /generate/3d` return `202` with a `Job`; `GET /jobs/{id}/wait` waits for its result. Start with the [Quick Start](./getting-started.html).

<!-- gen:catalog-summary -->
| Image | Video | Audio | 3D |
| --- | --- | --- | --- |
| 48 | 74 | 17 | 2 |
<!-- /gen -->

## The price before the spend

> [!TIP]
> `POST /jobs/cost` returns the exact credits your submit will hold and a `confirmation_token`; a quote reserves and charges nothing. `GET /pricing/models` is public. See [Billing](./billing.html).

## Check the refund outcome

A failed job carries `failure.code` and reports the ledger outcome in `failure.credits_refunded`: `true` means refunded; `false` means charged, including a content-filter refusal the provider billed for. An absent value does not confirm a refund; see [Errors](./errors.html).

<!-- gen:enum schema=GenerationErrorCode -->
| Value | Meaning |
| --- | --- |
| `out_of_credits` | the wallet cannot pay for the job. Nothing was submitted and nothing was charged. Top up, or submit a cheaper model or fewer seconds. |
| `rate_limit` | refused for now, not refused outright - the caller's own concurrency ceiling, or the provider's. Retry later; the same request will be accepted. |
| `prompt_nsfw` | a content filter refused the request or the result it produced, on safety grounds. Editing the prompt or the reference media is the fix. Whether the credits were refunded is `failure.credits_refunded`, not this code. |
| `ip_detected` | a content filter refused it for a real person's likeness or a protected work, rather than for safety. The fix is different from `prompt_nsfw` - change the reference image or the named subject, not the tone of the prompt - which is why it is its own code. |
| `job_failed` | the job ran and did not produce an asset for any other reason, including a provider error. The default for an unclassified failure. |
| `timeout` | the job ran past its time budget, or a `GET /jobs/{id}/wait` returned before the job reached a terminal status. On a failed job the work is over; on a `wait` the job may still be running. |
| `validation` | the request itself is not acceptable - a missing or malformed field, a model that does not support the capability asked of it, a duration the model will not render. Nothing was submitted and nothing was charged. Retrying unchanged will fail identically. |
| `confirmation_rejected` | the cost confirmation gate did not pass. Either a client showed the customer a quote and the customer declined, or a supplied confirmation token was refused. A submit that carries no confirmation token is never refused for this reason. |
| `canceled` | the job was canceled by its owner (`POST /jobs/{id}/cancel`), not broken. It is the code the SDK wait helpers raise for a `canceled` job; `cancellation` on the job says what the provider did and what was refunded. A canceled job carries no `failure`. |
| `job_not_cancellable` | `POST /jobs/{id}/cancel` refused (`409`) because the job already finished, or its finished result is already being delivered. The job will reach `succeeded` or `failed` on its own; nothing was changed. |
| `approval_required` | refused with `402` (title `Approval Needed`) because the generation would take an agent run past the price its customer approved (the `credit_ceiling` a guided preset's review card showed, sent with the brief). Nothing was submitted and nothing was charged. The detail names the generation's cost and the new run total; the agent must ask the customer to approve that total before it continues, never retry, split the job or switch models to fit. |
| `run_ended` | refused with `409` (title `Run Ended`) because the agent run this generation was started for (the turn its turn-scoped credential names) has already ended: the platform failed, swept or stopped the turn, or it finished and delivered its reply. Nothing was submitted and nothing was charged. The agent must stop working on that run, never retry or switch models; the customer's chat already shows how it ended. |
<!-- /gen -->

## Reusable subjects and looks

Reuse these in your generations or through the [Agent Sessions API](./agent-api.html).

| Resource | What you reuse |
| --- | --- |
| Characters | `character_ids` supplies an ordered cast of up to four characters. |
| Locations | Save a place's description and reference images. |
| Products | Reuse products imported from a store link or built from your images. |
| Brand kits | Keep palettes, fonts, logos and never-rules together. |
| Saved styles | Apply a prompt fragment and reference images with `style_id`. |
| Presets | Choose an outcome-named workflow that opens a creation tool or hands off to the agent. |

## From wherever you work

Use [nolgia.ai](https://nolgia.ai), the `nolgia` CLI, the MCP server for Claude Code and Cursor, skills for coding agents, or the NOLGIA Agent.

:::cards
- [Quick Start](./getting-started.html) icon=spot-library: Install a client and generate your first image and video.
- [Get your API key](./authentication.html) icon=spot-keys: Create and test a Personal Access Token.
- [Run MCP](./mcp.html) icon=spot-terminal: Generate inside your coding agent's conversation.
- [Agent Sessions API](./agent-api.html) icon=spot-agent: Create persistent conversations and collect their assets.
:::
