> ## Documentation Index
> Fetch the complete documentation index at: https://vetta.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# characters

> Trained, reusable on-screen personas — client.characters.

A character is a consistent on-screen persona trained once from reference photos, then pinned into every later image with `character` on [`media.images.generate`](/docs/sdk/media#imagesgenerate). Four methods, one per route. API detail: [Characters](/docs/api/characters.md).

Wherever a parameter is called `ref`, it takes a `chr_` id **or** the character's name — the API resolves both.

```ts theme={"system"}
client.characters.create(body: CharacterCreate, opts?: { idempotencyKey?: string }): Promise<Character>
client.characters.list(query?: ListQuery & { status?: "training" | "ready" | "failed"; scope?: "organization" | "platform" }): Promise<Page<Character>>
client.characters.get(ref: string): Promise<Character>
client.characters.delete(ref: string): Promise<Deleted>
```

* `create` — `POST /v1/characters`, answering `202` with the character in `training`. `CharacterCreate` is `{ name, description?, image_urls, persona?, style_pack?, consent }`: `name` 1–100 characters and unique among your characters, `image_urls` one to sixteen photos of the same person, each a stored file's `fil_` id or a public `http(s)` URL, and `consent` — **required**, `{ attested: true }` — your confirmation that the person in the photos is you, or has given you permission to create an AI likeness of them, and is not a public figure (kept on the character as `metadata.consent`, with who and when). Photos of a recognizable public figure are refused (`validation_failed` on `image_urls`) before anything is billed. **Paid**: the balance must cover one training first (`insufficient_credits` otherwise), and it is billed once, when the trainer accepts the photos. The client sends the required [`Idempotency-Key`](/docs/api/overview#idempotency) for you — pass `opts.idempotencyKey` to hold one across your own retries, so a retried create is the same training, never a second paid one; a second create under a name you already hold is refused before anything is trained.
* `list` — `GET /v1/characters`, your own newest first, then the prebuilt ones, cursor-paginated; `status` narrows it, and `scope` keeps only your own (`organization`) or only the prebuilt ones (`platform`).
* `get` — `GET /v1/characters/{ref}`. Each read advances the status from the trainer, so it is what you poll until `ready`.
* `delete` — `DELETE /v1/characters/{ref}`. A soft delete that frees the name; files it rendered keep their `source.character_id`. A prebuilt character cannot be deleted (`409 state_conflict`).

```ts theme={"system"}
const ava = await client.characters.create({
  name: "Ava",
  description: "Late twenties, freckles, copper bob, oversized denim jacket",
  image_urls: ["fil_01J9A...", "https://example.com/ava-profile.jpg"],
  persona: { niche: "Fashion · fit checks", voice: "Dry, quick, never salesy" },
  style_pack: ["Phone snap", "Quiet luxury"],
  consent: { attested: true },
});
let c = ava;
while (c.status === "training") {
  await new Promise((r) => setTimeout(r, 20_000));
  c = await client.characters.get(ava.id);
}
if (c.status === "failed") throw new Error(c.reason ?? "training failed");

// A still as Ava in a look, then animate it: the still carries her face, and its fil_ id is the
// video's first frame (a character video refuses any other).
const still = await client.media.images.generate({ prompt: "Ava on a rooftop at golden hour", character: ava.id, style: "Phone snap" });
const job = await client.media.videos.generate({ prompt: "she waves, the camera pushes in", character: ava.id, image_urls: [still.files[0].id] });
```

`Character` is the [character object](/docs/api/characters.md#the-character-object): `id`, `name`, `description`, `status`, `scope`, `persona`, `style_pack`, `sheet`, `source_images` (as you gave them), `thumbnail_url`, `reason`, `metadata`, `created_at`, `updated_at`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.