---
title: Characters and locations
description: Reusable subjects and places with reference images, a cast of up to four, and the identity gate that checks the render.
---

# Characters and locations

Keep a subject's identity and a place's appearance in reusable Library records. A character carries its name, canonical description and reference images; a location does the same for a room, storefront or set. Generation attaches their references and folds their canonical descriptions into the prompt verbatim.

## Characters

| Property | Value |
| --- | --- |
| Resource | `/characters` and `/characters/{id}` |
| Reference images | Up to eight; `primary_reference_asset_id` selects the identity anchor and defaults to the first reference |
| Continuity text | `canonical_description`, falling back to `description` on older records |
| Generation input | `character_id` for one subject, or ordered `character_ids` for a cast |
| Library | Personal or active organization; an organization record carries `organization_id` |

<!-- gen:endpoints tag=Characters -->
| Method | Path | What it does |
| --- | --- | --- |
| [POST](../api/#tag/characters/post/characters/autopilot) | `/characters/autopilot` | Roll a new Aura character and start its portrait render. |
| [POST](../api/#tag/characters/post/characters/{id}/sheets) | `/characters/{id}/sheets` | Generate a one-tap character sheet (split, five-view turnaround, or expression). |
| [GET](../api/#tag/characters/get/characters) | `/characters` | List the current user's characters, newest first. |
| [POST](../api/#tag/characters/post/characters) | `/characters` | Create a reusable character from existing image assets. |
| [GET](../api/#tag/characters/get/characters/{id}) | `/characters/{id}` | Fetch one of the current user's characters with fresh signed reference URLs. |
| [PATCH](../api/#tag/characters/patch/characters/{id}) | `/characters/{id}` | Update a character's name, description, or reference images. |
| [DELETE](../api/#tag/characters/delete/characters/{id}) | `/characters/{id}` | Delete one of the current user's characters. |
<!-- /gen -->

Read `readiness` before selecting a reference: `ready` means one front-facing face. `needs_front_view`, `no_face`, `multiple_faces` and `unverified` are advisory states, not a promise that the identity gate will pass. `GET /characters/{id}` also includes recent `fidelity_history`; list and write responses omit that history.

<!-- gen:fields schema=Character only=id,name,canonical_description,primary_reference_asset_id,reference_assets,readiness,voice,fidelity_history -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `name` | string | Yes |  |
| `canonical_description` | string | No | The character's canonical written description - the asset bible entry (face, hair, build, wardrobe, anchor) reused VERBATIM by every downstream generation.… |
| `primary_reference_asset_id` | string, nullable | No | The reference asset that anchors the character's identity: sheet actions attach it as the character reference and identity scoring runs against it. Defaults to the first reference asset when unset. |
| `reference_assets` | array of `Asset` | Yes | Reference images (image assets) in display order, each with a fresh signed URL. |
| `voice` | `CharacterVoice` | No | Used by POST /generate/audio (character_id) and by video generation with use_character_voice true; absent when the character has no voice. |
| `readiness` | string | No | Whether the character's PRIMARY reference can anchor its identity, derived from the face verdict stored when the reference joined the character.… |
| `fidelity_history` | array of `CharacterFidelitySample` | No | The character's most recent identity-gated renders, newest first: the `identity_score` the Aura gate measured against the primary reference on each image or video generated with this `character_id`.… |
<!-- /gen -->

## Locations

| Property | Value |
| --- | --- |
| Resource | `/locations` and `/locations/{id}` |
| Reference images | Up to eight; the primary reference anchors the place |
| Continuity text | `canonical_description`, falling back to `description` when empty |
| Generation input | `location_id`, alongside a character or cast |
| Identity scoring | None: the identity gate scores faces, not places |

<!-- gen:endpoints tag=Locations -->
| Method | Path | What it does |
| --- | --- | --- |
| [GET](../api/#tag/locations/get/locations) | `/locations` | List the current user's locations, newest first. |
| [POST](../api/#tag/locations/post/locations) | `/locations` | Create a reusable location from existing image assets. |
| [GET](../api/#tag/locations/get/locations/{id}) | `/locations/{id}` | Fetch one of the current user's locations with fresh signed reference URLs. |
| [PATCH](../api/#tag/locations/patch/locations/{id}) | `/locations/{id}` | Update a location's name, descriptions, primary anchor or reference images. |
| [DELETE](../api/#tag/locations/delete/locations/{id}) | `/locations/{id}` | Delete one of the current user's locations. |
<!-- /gen -->

A location needs no training. Its canonical description stays unchanged across scenes, and its primary reference uses an image-reference slot on an image model or an element-reference slot on a video model. A location without an image contributes its description only.

## Use them in a generation

| Input | Image behavior | Video behavior |
| --- | --- | --- |
| `character_id` | Primary image becomes the face reference; requires an Aura-compatible model with room for the reference and `num_images: 1` | Primary image becomes an element reference |
| `character_ids` | Ordered cast of up to four; lead supplies the face reference, then the other cast references follow | Ordered cast of up to four; references keep cast order after the caller's own references; `@Name` is rewritten to the member's `@ImageN` slot |
| `use_character_voice` | Not an image field | Opt in to the lead's clip voice as the next audio reference; requires a model with an available audio slot and an acceptable clip length |
| `location_id` | Adds the place's description and reference | Adds the place's description and an element reference |

The image request fields are generated from the contract:

<!-- gen:fields schema=GenerateImageRequest only=character_id,character_ids,location_id -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `character_id` | string, nullable | No | One of your characters (`GET /characters`, created on the Create Characters page).… |
| `character_ids` | array of string, nullable | No | An ORDERED cast of up to 4 of your characters rendered together (two-person dialogue scenes, duets, family commercials).… |
| `location_id` | string, nullable | No | One of your locations (`GET /locations`): the place this render is set in.… |
<!-- /gen -->

The video fields include the explicit voice opt-in:

<!-- gen:fields schema=GenerateVideoRequest only=character_id,character_ids,use_character_voice,location_id -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `character_id` | string, nullable | No | One of your characters (`GET /characters`).… |
| `use_character_voice` | boolean, nullable | No | Attaches the lead character's (character_id, or the first of character_ids) voice clip as a reference audio track (audio_asset_ids, emitted after your own audio tracks and audio_urls, taking the next @Audio slot) and adds a voice line to the prompt.… |
| `character_ids` | array of string, nullable | No | An ORDERED cast of up to 4 of your characters rendered together in one clip.… |
| `location_id` | string, nullable | No | One of your locations (`GET /locations`): the place this clip is set in.… |
<!-- /gen -->

> [!WARNING]
> Check the model's reference budgets before casting. A cast or location that cannot fit is refused with `400`, never silently dropped. Do not combine `character_id` with `face_reference_asset_id`; they supply competing identities. Duplicate cast members and foreign ids are also refused.

When both `character_id` and `character_ids` are supplied, the single id must be a member of the cast. The first member is the lead, including for `use_character_voice`. Voice opt-in may change the cost on models billed by the reference audio's length; quote the full request first.

## Autopilot

| Property | Value |
| --- | --- |
| Start | `POST /characters/autopilot` |
| Returns | `202` with a portrait `job`, `canonical_description` and eight rolled `axes` |
| Model | `grok-imagine-image` |
| Billing | The equivalent image generation price |
| Next step | Wait for the portrait, then create the character with `POST /characters` |

Autopilot rolls heritage, age band, hair color, build, hair style, eye color, wardrobe and an anchor detail. Consecutive rolls differ on at least two of the four core axes. It starts a portrait job; it does not create the character record for you. Store its returned `canonical_description` unchanged when creating that record.

```bash title="Autopilot request — example"
$ curl -sS -X POST https://api.nolgia.ai/v1/characters/autopilot \
  -H "Authorization: Bearer $NOLGIA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

This illustrative response is built from `AutopilotCharacterResponse`, not a production capture.

```json title="202 — example from the response schema"
{
  "job": {
    "id": "b9f4319a-239e-4907-a9bb-406be1f0c2b8",
    "user_id": "4961eaef-70a6-4e9b-b746-c86ad3e62077",
    "modality": "image",
    "model": "grok-imagine-image",
    "status": "queued",
    "created_at": "2026-09-21T04:00:00Z",
    "updated_at": "2026-09-21T04:00:00Z"
  },
  "canonical_description": "A middle-aged woman with short dark curls, brown eyes, a sturdy build, a navy work jacket and a small silver brooch.",
  "axes": {
    "heritage": "mixed heritage",
    "age_band": "middle-aged",
    "hair_color": "dark",
    "build": "sturdy",
    "hair_style": "short curls",
    "eye_color": "brown",
    "wardrobe": "navy work jacket",
    "anchor": "small silver brooch"
  }
}
```

<!-- gen:fields schema=AutopilotCharacterResponse -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `job` | `Job` | Yes |  |
| `canonical_description` | string | Yes | The rolled canonical written description. Store it on the character record unchanged when creating the character from this roll - it is the continuity contract for every downstream generation. |
| `axes` | object | Yes | The variety-engine roll: all 8 axis values (heritage, age_band, hair_color, build, hair_style, eye_color, wardrobe, anchor).… |
<!-- /gen -->

<!-- gen:fields schema=Job only=id,user_id,modality,model,status,created_at,updated_at,asset,failure -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `user_id` | string | Yes |  |
| `modality` | `Modality` | Yes |  |
| `model` | string | Yes |  |
| `status` | `JobStatus` | Yes |  |
| `asset` | `Asset` | No |  |
| `failure` | `JobFailure` | No |  |
| `created_at` | string | Yes |  |
| `updated_at` | string | Yes |  |
<!-- /gen -->

For an existing character, `POST /characters/{id}/sheets` creates a `split`, `turnaround` or `expression` sheet on `gpt-image-2`, billed like that model's image generation. It needs at least one reference image. Wearable references and a named wardrobe outfit share a budget of three extra references; overflow is refused instead of trimming the outfit.

<!-- gen:fields schema=CreateCharacterSheetRequest -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | `CharacterSheetKind` | Yes |  |
| `wearable_reference_asset_ids` | array of string | No | Image assets (owned by the caller) showing exact wearable items - garments, jewelry, eyewear, footwear - that must render EXACTLY as shown on the character in every view: never redesigned, restyled, recolored, or reinterpreted.… |
| `outfit` | string, nullable | No | The name of one of the character's wardrobe outfits (`Character.wardrobe`).… |
| `project_id` | string, nullable | No | Files the generated sheet into this caller-owned project. |
<!-- /gen -->

## The identity gate

| Property | Value |
| --- | --- |
| Score | ArcFace-family cosine similarity, from −1 to 1 |
| Passing threshold | `identity_score >= 0.60` |
| Automatic retry | At most one re-roll; the better-scoring attempt is delivered |
| Multi-character result | `identity_score` is the weakest cast member's score |
| Video sampling | Frames at 2 fps; each member uses its best matching face/frame |
| Unavailable scoring | Identity fields are absent or null; the reference still conditioned the generation |

<!-- gen:fields schema=Asset only=identity_score,identity_rerolls,identity_gate_passed,character_scores -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `identity_score` | number, nullable | No | ArcFace-family cosine similarity against the generation's identity reference (Aura identity gate).… |
| `identity_rerolls` | integer, nullable | No | Number of completed automatic identity re-rolls behind this render (0 or 1 — the gate re-rolls at most once, then delivers the better-scoring attempt). Present only alongside `identity_score`. |
| `identity_gate_passed` | boolean, nullable | No | Whether `identity_score` clears the 0.60 identity gate.… |
| `character_scores` | array of `AssetCharacterScore`, nullable | No | Per-character identity outcome of a multi-character cast render (`character_ids`), in cast order: each member's own ArcFace-family cosine (its best-matching face in the render, or the best frame of a clip) and whether it clears the 0.60 gate.… |
<!-- /gen -->

<!-- gen:fields schema=AssetCharacterScore -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `character_id` | string | Yes | The cast member (`GET /characters/{id}`). |
| `identity_score` | number | Yes | This member's cosine against the delivered render. |
| `identity_gate_passed` | boolean | Yes | Whether this member clears the 0.60 identity gate. |
<!-- /gen -->

> [!NOTE]
> A delivered asset can have `identity_gate_passed: false`: both attempts missed the threshold and the better attempt was delivered. Check the boolean and per-member `character_scores` before treating a cast render as approved. An absent score does not mean it passed.

Characters without a reference image contribute only their description and remain unscored. Locations are not scored by the face gate.

## Related reusable inputs

[Products](../api/#tag/products) carry reusable product images and details into a generation through `product_id`.

[Brand kits](./styles.html#brand-kits) carry palettes, fonts, logos and never-rules through `brand_kit_id`.

[Elements](../api/#tag/elements) provide reusable reference inputs through `element_ids`; they count against the selected model's reference budget.

## Next steps

:::cards
- [Common model arguments](./model-arguments.html): Check model capabilities and compose compatible reference inputs.
- [Styles and looks](./styles.html): Add a saved look, brand rules and a camera move.
:::
