---
title: Avatar UGC video
description: Call the Avatar video Format by Sume from your backend to turn a script into a creator-style talking-head video with captions and soundtrack.
---

**The job:** hand it a script and get back a finished talking-head video — a catalog avatar cast to
the brief, captions burned on, soundtrack muxed. The Format owns the whole preview-then-generate
pipeline, so you send words and read back a video URL.

**Use it when** you need creator-style UGC ads at volume and only the script changes. For product
imagery and motion ads without a presenter, use [Product promo](/formats/product-promo).

First-party slug: `sume-avatar-video-generation`.

## 1. Address it

Call it at `sume/sume-avatar-video-generation` with any key that carries the scopes below. Nothing
to fork, nothing to install: the catalog Format is shared and unowned, and the run, its media and
its spend belong to the key that called.

Forking is still available when you want to *change* the Format — open
[Avatar video generation in the Format library](https://www.sume.com/agents/format) and press
**Fork** for an editable copy owned by you. The fork keeps the body and the spend cap and takes a
new slug (the dashboard suggests `sume-avatar-video-generation-custom`, since a fork must not reuse
its source's slug); its detail page shows it as `{your_handle}/{slug}`. That is a customization
step, not a prerequisite for calling.

## 2. Scopes

| Scope | Needed for |
|---|---|
| `formats:read` | Read the Format, read and list its runs. |
| `formats:write` | Start a run, cancel a run. |

Keys created before Formats shipped do not carry these, and scopes cannot be added to an existing
key — mint a new one at [API Keys](https://www.sume.com/dashboard/api-keys) and rotate to it.
Service-account keys cannot start Format runs.

## 3. Call it

```bash
export SUME_API_KEY="sume_live_..."

curl -sS -X POST "https://api.sume.com/v1/formats/sume/sume-avatar-video-generation/runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "instruction": "Make a 20-second vertical UGC ad from this script. Warm, casual delivery.",
    "input": {
      "script": "I tried three trail shoes this month. This is the only pair I still wear.",
      "aspect_ratio": "9:16",
      "captions": true,
      "product_url": "https://example.com/products/trail-runner"
    },
    "generation_spend_cap_usd": 30
  }'
```

The opaque `skl_…` path stays valid for clients that already store it; new integrations should
use `{handle}/{slug}`.

An accepted run returns `202`:

```json
{
  "data": {
    "id": "run_...",
    "object": "format.run",
    "format": { "id": "skl_...", "slug": "sume-avatar-video-generation", "version": 1 },
    "status": "queued",
    "status_url": "https://api.sume.com/v1/format-runs/run_.../status",
    "result_url": "https://api.sume.com/v1/format-runs/run_.../result",
    "created_at": "2026-08-02T09:00:00.000Z"
  }
}
```

Send `Idempotency-Key` on every call. A replay with the same body returns `200` and the original
run; a replay with a different body returns `409 idempotency_conflict`.

### About `input`

`input` is free-form JSON, fenced into the prompt as caller data and never as instructions —
**concatenated**, not validated as a hard wire schema. The Format body decides which keys it
reads, so the example above is a realistic shape rather than a contract. Keep it small and
literal: at most 64 keys and 8 KiB. See
[Calling a Format](/formats/call#input-caller-data).

Leave casting to the Format unless you have a reason not to. It searches the avatar catalog against
your script and brief; naming an `avatar_handle` yourself pins the result and skips that step.

## 4. Spend cap

Avatar video is the most expensive thing in the catalog — a run may generate music, stills, and a
video before it finishes — so set the cap deliberately.

The Format's cap is what a run inherits when it names none. Read the current value from
`PublicFormat.generation_spend_cap_usd_micros`. A Format that never named one gets the platform
default of **$400**; the ceiling you can set is $500.

`generation_spend_cap_usd` on a run names that run's own ceiling, up to $500 — above the Format's
own cap is honored, above $500 is an error.

A cap set too low is the usual reason a video run finishes without a video. If `artifacts[]` has
stills but no video, raise the cap before changing the prompt.

## 5. Poll, then read the result

Avatar video runs are long. Poll with backoff rather than a tight loop, or supply
`communication.webhook_url` and let Sume deliver the terminal receipt to you.

```bash
curl -sS "https://api.sume.com/v1/format-runs/$RUN_ID" \
  -H "Authorization: Bearer $SUME_API_KEY"
```

Statuses are `queued`, `processing`, `completed`, `failed`, `canceled`, `skipped`. Poll
`status_url` for the cheap check; it returns just the status fields and `next_action`.

A `completed` receipt carries `output`, `artifacts[]` — every durable file the run produced — and
`primary_output_url`, which is the finished video. Media URLs are durable `media.sume.com` HTTPS
URLs and do not expire.

Cancel a run in flight:

```bash
curl -sS -X POST "https://api.sume.com/v1/format-runs/$RUN_ID/cancel" \
  -H "Authorization: Bearer $SUME_API_KEY"
```

Cancel is a no-op once the run is terminal; the current receipt comes back either way.

## Two things that surprise people

**A fresh fork reads as inactive until its first run.** `GET /v1/formats/{format_id}` reports
`status: "inactive"` and `api_trigger_enabled: false` on a copy you just made, because both are
read off a runner that is provisioned lazily. Do not gate your integration on those fields being
true — the first `POST .../runs` provisions the runner and the run proceeds normally.
`sume/{slug}` itself always reads `active`, since the catalog is callable by definition.

**The preview gate does not stop an API run.** In chat this Format shows you preview stills and
waits for approval before generating the video. Over the API nobody is there, so the run is told
those approvals are already granted and to carry on to the paid step within the spend cap. A run
that genuinely cannot finish — no avatar matched the brief, say — comes back `failed` with
`output_error.code` of `unattended_blocked`, never a half-finished `completed`.

## Next

- [Calling a Format](/formats/call) — the full invoke contract and every error code
- [Runs and results](/formats/runs) — receipts, versioning, cancelation
- [Structured output](/formats/structured-output) — bind a schema and get typed JSON back
- [Product promo](/formats/product-promo) — the product-imagery counterpart to this Format
- [Generate avatar video](/models/avatar-videos) — the underlying model API, if you want to drive the pipeline yourself
- [OpenAPI](https://api.sume.com/reference) — exact request and response schemas
