---
title: Styles and looks
description: Saved styles applied with style_id, brand kits, the camera-move library, and the built-in color-grade presets for Studio.
---

# Styles and looks

Use a saved style to repeat a look, a brand kit to carry brand rules, a named motion to direct the camera, and a color preset to grade a Studio composition. These inputs affect different stages of the result and can be combined within the chosen model's capabilities.

## Saved styles

Saved styles are a reusable look: a prompt fragment plus reference images, applied with `style_id`.

| Property | Value |
| --- | --- |
| Resource | `/styles` and `/styles/{id}` |
| Generation input | `style_id` on image or video requests |
| Prompt | `prompt_fragment` is appended after your own words; it never replaces them |
| Images | Up to four reference images; the first is the style's `swatch` |
| Model hint | A client suggestion only; the API never switches the requested model |
| Default | The output project's pinned style applies when `style_id` is omitted |

<!-- gen:endpoints tag=Styles -->
| Method | Path | What it does |
| --- | --- | --- |
| [GET](../api/#tag/styles/get/styles) | `/styles` | List saved styles in your library, newest first. |
| [POST](../api/#tag/styles/post/styles) | `/styles` | Create a saved style. |
| [GET](../api/#tag/styles/get/styles/{id}) | `/styles/{id}` | Fetch a saved style with fresh signed reference URLs. |
| [PATCH](../api/#tag/styles/patch/styles/{id}) | `/styles/{id}` | Update a saved style, replacing references only when provided. |
| [DELETE](../api/#tag/styles/delete/styles/{id}) | `/styles/{id}` | Delete a saved style. |
<!-- /gen -->

An explicit `style_id` overrides the project's style for one generation. Style images follow the subject references and use only the remaining reference budget. An image that does not fit is left out; the prompt fragment still applies.

> [!NOTE]
> For video, the style's swatch rides only when the clip already has another visual input, such as a character, reference image, start frame or reference video. A text-only clip gets the fragment alone, so a lone swatch does not become the scene's subject. `source_video_asset_id` regeneration cannot take an explicit style and skips the project's pinned style.

```bash title="List saved styles — example"
$ curl -sS https://api.nolgia.ai/v1/styles \
  -H "Authorization: Bearer $NOLGIA_TOKEN"
```

This response is built from `SavedStyleList` and `SavedStyle`, not a production capture.

```json title="200 — example from the response schemas"
{
  "styles": [
    {
      "id": "60825d85-9c86-4146-9715-386a1aa2743c",
      "user_id": "4961eaef-70a6-4e9b-b746-c86ad3e62077",
      "name": "Paper cut",
      "prompt_fragment": "Layered paper shapes with visible cut edges and soft side lighting.",
      "model_hint": "flux-pro",
      "reference_images": [],
      "created_at": "2026-09-21T04:00:00Z",
      "updated_at": "2026-09-21T04:00:00Z"
    }
  ]
}
```

<!-- gen:fields schema=SavedStyleList -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `styles` | array of `SavedStyle` | Yes |  |
<!-- /gen -->

<!-- gen:fields schema=SavedStyle -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `swatch` | `Asset` | No | The style key image: the first reference image, attached first when the style rides a generation. Omitted when the style has no reference images. |
| `id` | string | Yes |  |
| `user_id` | string | Yes |  |
| `organization_id` | string | No |  |
| `name` | string | Yes |  |
| `prompt_fragment` | string | Yes | Appended after your own prompt when style_id is passed, never replaces it. |
| `model_hint` | string | Yes | An ImageModel id the look renders best on, or empty. Clients default the picker to it, the API never switches models for you. |
| `reference_images` | array of `Asset` | Yes | Reference images in display order with fresh signed URLs, appended within the model caps. |
| `created_at` | string | Yes |  |
| `updated_at` | string | Yes |  |
<!-- /gen -->

## Brand kits

Brand kits are reusable palettes, fonts, logos and never-rules for generation, scoped to the personal library or the active organization.

| Property | Value |
| --- | --- |
| Resource | `/brand-kits` and `/brand-kits/{id}` |
| Generation input | `brand_kit_id` and `brand_kit_mode` on image or video requests |
| Default kit | The explicit project's kit, or the active agent session's project kit |
| Prompt | The compact brand block is appended after your own words |
| Logo | Attaches only when supported and a spare reference slot remains; never displaces a subject reference |
| Outcome | Asset generation metadata records `brand_logo_attached` |

<!-- gen:endpoints tag=BrandKits -->
| Method | Path | What it does |
| --- | --- | --- |
| [GET](../api/#tag/brandkits/get/brand-kits) | `/brand-kits` | List the current user's brand kits, newest first. |
| [POST](../api/#tag/brandkits/post/brand-kits) | `/brand-kits` | Create a reusable brand kit from brand rules and existing image assets. |
| [GET](../api/#tag/brandkits/get/brand-kits/{id}) | `/brand-kits/{id}` | Fetch one of the current user's brand kits with fresh signed logo URLs. |
| [PUT](../api/#tag/brandkits/put/brand-kits/{id}) | `/brand-kits/{id}` | Replace a brand kit's full contents. |
| [DELETE](../api/#tag/brandkits/delete/brand-kits/{id}) | `/brand-kits/{id}` | Delete one of the current user's brand kits. |
<!-- /gen -->

### brand_kit_mode

| Value | Behavior |
| --- | --- |
| `full` | Default: append the brand block and attach the logo where it fits |
| `prompt_only` | Append the brand block without attaching the logo |
| `off` | Disable both an explicit kit and the project's kit; cannot be combined with `brand_kit_id` |

Image enhancement, expansion and masked requests do not attach a brand logo. Video edit and extend tasks do not attach it either; regeneration with `source_video_asset_id` refuses an explicit kit and skips an implied project kit. The model's reference limits still apply.

<!-- gen:fields schema=GenerateImageRequest only=style_id,brand_kit_id,brand_kit_mode -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `brand_kit_id` | string, nullable | No | One of your brand kits (`GET /brand-kits`).… |
| `brand_kit_mode` | `BrandKitMode` | No |  |
| `style_id` | string, nullable | No | One of your saved styles (`GET /styles`).… |
<!-- /gen -->

<!-- gen:fields schema=GenerateVideoRequest only=style_id,brand_kit_id,brand_kit_mode -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `brand_kit_id` | string, nullable | No | One of your brand kits (`GET /brand-kits`).… |
| `brand_kit_mode` | `BrandKitMode` | No |  |
| `style_id` | string, nullable | No | One of your saved styles (`GET /styles`).… |
<!-- /gen -->

## Camera moves

The camera-move library is public, embedded and identical for every caller. Send its stable `id` as `motion_id` on a video request; the server appends the chosen strength's exact prompt fragment as a sentence without replacing your direction.

| Property | Value |
| --- | --- |
| Catalog | `GET /motions`, anonymous |
| Input | `motion_id` and optional `motion_strength` |
| Strengths | `subtle`, `medium`, `strong`; omitted strength uses the move's `default_strength` |
| Models | All video models, including text-to-video, image-to-video and `shots[]` requests |
| Preview clips | `preview_url` is reserved and currently null |

<!-- gen:endpoints paths=/motions -->
| Method | Path | What it does |
| --- | --- | --- |
| [GET](../api/#tag/motions/get/motions) | `/motions` | List the camera-move library for video generation. Public, embedded, identical for every caller. |
<!-- /gen -->

```bash title="Read the camera-move library"
$ curl -sS https://api.nolgia.ai/v1/motions
```

This is the first complete entry from an anonymous production read; the rest of `motions` is omitted.

```json title="200 — production camera-move entry, trimmed catalog"
{
  "motions": [
    {
      "category": "dolly",
      "default_strength": "medium",
      "description": "The camera moves toward the subject, tightening the frame.",
      "id": "push-in",
      "name": "Push-in",
      "preview_url": null,
      "strengths": [
        {
          "prompt_fragment": "Camera: a gentle, barely perceptible push-in toward the subject on a smooth dolly, the framing tightening only slightly by the last frame.",
          "strength": "subtle"
        },
        {
          "prompt_fragment": "Camera: a steady push-in toward the subject on a smooth dolly, the framing tightening from a medium shot to a close-up over the clip.",
          "strength": "medium"
        },
        {
          "prompt_fragment": "Camera: a fast, decisive push-in that drives from a wide shot to a tight close-up on the subject, momentum building to the last frame.",
          "strength": "strong"
        }
      ]
    }
  ]
}
```

<!-- gen:fields schema=CameraMoveList -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `motions` | array of `CameraMove` | Yes | Moves in display order. |
<!-- /gen -->

<!-- gen:fields schema=CameraMove -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The stable `motion_id` a request sends. |
| `name` | string | Yes | The customer-facing label. |
| `description` | string | Yes | One sentence on what the move does on screen (the text description standing in for a preview clip). |
| `category` | string | Yes | Chip grouping (`dolly`, `orbit`, `crane`, `pan`, `focus`, `handheld`, `zoom`, `static`). |
| `default_strength` | `CameraMoveStrength` | Yes |  |
| `strengths` | array of `CameraMoveStrengthOption` | Yes | One entry per strength, subtle first. |
| `preview_url` | string, nullable | Yes | An example clip of the move. Reserved; `null` on every entry today. |
<!-- /gen -->

<!-- gen:fields schema=CameraMoveStrengthOption -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `strength` | `CameraMoveStrength` | Yes |  |
| `prompt_fragment` | string | Yes | The exact sentence the server appends to the prompt at this strength. |
<!-- /gen -->

> [!WARNING]
> A `motion_strength` without `motion_id` is refused with `400`. Use a published move id; an unknown id is also `400`. If an enhanced prompt already contains the exact fragment, the server does not append it twice.

## Color presets

Built-in color-grade presets are LUT looks for Studio compositions. Their catalog is public and identical for every caller; the render job bakes the grade into the exported MP4.

| Property | Value |
| --- | --- |
| Catalog | `GET /color-presets`, anonymous |
| Grade input | `data-color-grade` on timed HTML elements or the canvas, and `colorGrade` in `nolgia-edits.json` |
| Stable identity | The preset's `slug`, used as `colorGrade.preset` |
| Groups | Present `film` first; `looks` contains the legacy stylized set |
| LUT download | `GET /color-presets/{slug}/cube`, a public 33-point `.cube` text file |

<!-- gen:endpoints tag=ColorPresets -->
| Method | Path | What it does |
| --- | --- | --- |
| [GET](../api/#tag/colorpresets/get/color-presets) | `/color-presets` | List the built-in color-grade presets ("LUT looks") for studio compositions. Public — the embedded catalog is identical for every caller. |
| [GET](../api/#tag/colorpresets/get/color-presets/{slug}/cube) | `/color-presets/{slug}/cube` | Download a color preset's 33-point `.cube` LUT — the pure preset op chain (no manual adjustments), baked on demand from the embedded manifest. Public, aggressively cacheable. |
<!-- /gen -->

```bash title="Read the built-in grade catalog"
$ curl -sS https://api.nolgia.ai/v1/color-presets
```

This is the first complete preset from an anonymous production read; the rest of `presets` is omitted.

```json title="200 — production color preset, trimmed catalog"
{
  "version": 2,
  "presets": [
    {
      "category": "motion",
      "description": "The modern film workhorse: tungsten balanced, warm shadows, soft highlight roll.",
      "group": "film",
      "name": "Kodak Vision3 500T",
      "slug": "kodak-vision3-500t"
    }
  ]
}
```

<!-- gen:fields schema=ColorPresetList -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `version` | integer | Yes | Manifest version; bumps when the recipe set changes. |
| `presets` | array of `ColorPreset` | Yes | Presets in manifest order. |
<!-- /gen -->

<!-- gen:fields schema=ColorPreset -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `slug` | string | Yes | Stable identity of the preset — the value a `colorGrade`'s `preset` field references. |
| `name` | string | Yes | Display name. |
| `description` | string | Yes | One-line description of the look. |
| `category` | string | No | Editorial category within its group. Film-stock presets use motion \| stills \| mono \| finish \| camera; the legacy looks use look. Empty on presets recorded before the field existed. |
| `group` | string | No | Catalog group. `film` is the primary set (real film stock emulations, round 39); `looks` is the legacy stylized set kept as a secondary group. Clients should present `film` first. |
<!-- /gen -->

The `.cube` download contains the pure preset operations; manual grade adjustments are not included. Composition exports include their color-grade LUTs under `luts/`.

## Next steps

:::cards
- [Characters and locations](./characters.html): Keep the subject and place consistent across generations.
- [Compositions and Studio export](./compositions.html): Bake looks into renders and export editable timelines.
:::
