> For the complete documentation index, see [llms.txt](https://bountyv.gitbook.io/vdocs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bountyv.gitbook.io/vdocs/youtube-tools-api/thumbnail-generate.md).

# Thumbnails

Generate 1–4 social/YouTube thumbnail variants from a brief and reference images, with optional burned-in title text.

```
POST /api/v1/thumbnail/generate
```

Synchronous. Renders all variants in parallel and returns them in one response. Each variant that renders successfully is billed individually — failed variants are never charged.

## Authentication

Unlike the rest of the API, the Thumbnail endpoints take your key as an **`apiKey` field in the request body** — not the `Authorization` header — so it can be posted directly from a browser form. The key is still validated, rate-limited, and product-gated exactly like a Bearer call. See [Authentication](/vdocs/authentication.md) for general details.

## Modes

`mode=face_ref` (default) builds the thumbnail from a style/emotion/palette brief plus up to 3 face reference photos. `mode=scene` composes from labeled reference images (Character / Background / Style / Extra) and requires a scene description in `customPrompt`.

* `scene` mode requires a non-empty `customPrompt` and at least one of the four scene refs.
* `face_ref` mode requires a `title` or a `customPrompt`.

## Square cover art

`aspect=1x1` returns square JPG cover art sized for music distributors rather than a video platform — DistroKid, Apple Music, and Spotify all require a square RGB JPEG. Both `squareSize` values clear DistroKid's 1000×1000 minimum and 10MB ceiling.

| `squareSize`     | Description                                                                                                                                                                |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `2048` (default) | Rendered natively at 2048 and returned as-is — no resampling at any stage.                                                                                                 |
| `3000`           | The size DistroKid, Apple Music, and Spotify publish as ideal. Downscaled from a native 4096 render, making it the crisper of the two — it costs a 4K generation upstream. |

Square renders are composed as cover art, not as thumbnails — the model is told to make a single strong image that survives a 64×64 playlist row, rather than a click-through-optimized feed thumbnail.

## Request

**Content-Type:** `multipart/form-data`

| Field             | Type                            | Required | Default     | Description                                                                                                                     |
| ----------------- | ------------------------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`          | string                          | ✅        | —           | Your Substance API key (`sk_live_...`).                                                                                         |
| `mode`            | `"face_ref"` \| `"scene"`       | —        | `face_ref`  | Generation mode (see above).                                                                                                    |
| `variants`        | integer                         | —        | `3`         | How many variants to render, 1–4. Each successful one is billed.                                                                |
| `title`           | string                          | —        | —           | Headline text. In `face_ref` mode, either this or `customPrompt` is required.                                                   |
| `subtext`         | string                          | —        | —           | Optional supporting sub-line rendered beneath the title.                                                                        |
| `customPrompt`    | string                          | —        | —           | Freeform scene description. **Required in `scene` mode.** In `face_ref` mode it overrides the structured brief.                 |
| `style`           | enum                            | —        | `cinematic` | `mrbeast` · `cinematic` · `vlog` · `drama` · `news` · `gaming` · `reaction` · `tech` · `luxury`.                                |
| `emotion`         | enum                            | —        | `shocked`   | `shocked` · `excited` · `smug` · `angry` · `surprised` · `curious` · `determined` · `confident` · `scared` · `laughing`.        |
| `palette`         | enum                            | —        | `auto`      | `auto` · `vibrant` · `dark` · `warm` · `cool` · `neon` · `monochrome`.                                                          |
| `aspect`          | `"16x9"` \| `"9x16"` \| `"1x1"` | —        | `16x9`      | `16x9` = widescreen (1280×720 PNG). `9x16` = vertical shorts (720×1280 PNG). `1x1` = square cover art (JPG) — see `squareSize`. |
| `squareSize`      | `2048` \| `3000`                | —        | `2048`      | Only read when `aspect=1x1`. Both are real renders, neither is upscaled.                                                        |
| `renderText`      | boolean                         | —        | `true`      | When `false`, the image is rendered clean with no burned-in title/subtext.                                                      |
| `faces`           | file\[]                         | —        | —           | Up to 3 face reference photos (`face_ref` mode). Repeat the field per file.                                                     |
| `ref_character`   | file                            | —        | —           | Scene mode: the subject/character to place.                                                                                     |
| `ref_background`  | file                            | —        | —           | Scene mode: the environment/setting.                                                                                            |
| `ref_style`       | file                            | —        | —           | Scene mode: lighting/colour-grade reference.                                                                                    |
| `ref_extra`       | file                            | —        | —           | Scene mode: optional extra element (prop, texture, composition cue).                                                            |
| `ref_extra_label` | string                          | —        | —           | Scene mode: custom label describing what `ref_extra` is.                                                                        |

## Response

Each entry in `items` contains a 1-hour signed image URL (or a `data:` URL fallback if signing failed) and a `generation_id` you can re-fetch later. Any variants that failed appear in `failures`. The top-level `width`, `height`, and `format` describe every item in the response — all variants share one output spec.

```json
{
  "items": [
    { "variant": 0, "image": "https://…signed…", "generation_id": "gJ8nP3kQ2m" },
    { "variant": 1, "image": "https://…signed…", "generation_id": "kP2mQ9nR4x" }
  ],
  "width": 1280,
  "height": 720,
  "format": "png",
  "failures": [
    { "variant": 2, "error": "model returned no image" }
  ],
  "elapsedMs": 14820,
  "charged_cents": 50,
  "new_balance_cents": 4950
}
```

Billing is preflighted against `variants × per-variant price`, then each rendered variant is charged on completion. If every variant fails you get a `502` and `charged_cents: 0`.

## Example

```bash
curl -X POST https://substance-api.com/api/v1/thumbnail/generate \
  -F "apiKey=$SUBSTANCE_API_KEY" \
  -F "mode=face_ref" \
  -F "variants=3" \
  -F "title=I Survived 24 Hours In Antarctica" \
  -F "style=mrbeast" \
  -F "emotion=shocked" \
  -F "aspect=16x9" \
  -F "faces=@me.jpg"
```

## Errors

| Status | When                                                                                                                                  |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Missing `apiKey`; scene mode missing prompt/refs; face\_ref mode missing title and prompt; more than 3 faces; or malformed form data. |
| `401`  | Missing/invalid/revoked API key.                                                                                                      |
| `402`  | Balance below the preflight total for the requested variants.                                                                         |
| `403`  | Account does not have the `image` product enabled.                                                                                    |
| `502`  | All variants failed upstream; nothing was charged.                                                                                    |

See [Errors](/vdocs/errors.md) for full details.

## Pricing

Billed per call — see [Credits & pricing](/vdocs/account/credits.md) for current rates.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bountyv.gitbook.io/vdocs/youtube-tools-api/thumbnail-generate.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
