---
title: "Create an element"
method: POST
path: "/elements"
tags: ["Elements"]
---

# Create an element

`POST /elements`

Saves a reusable element (a person/character, product/prop, or place) with a reference photo.

**Photo source, one of:**
- `imageUrl`: a public URL; we download and store it.
- `imageAssetId`: an asset from `POST /uploads` with purpose `element-image`.

**After creating:** mention it in scripts as `@handle` (returned in the response) to put it in faceless videos, or use a character's `id` as `avatarId` for talking-head videos.

The photo is the single source of truth for how the element looks. Use `description` for context (what it is, when to use it), never for appearance.

## Request body

- object
  - `name` string, required — Element name, used to build the @handle. Letters, numbers, spaces, and hyphens work best (e.g. "Dhiva", "Red Bottle").
  - `type` 'character' | 'prop' | 'location', required — `character` = a person or mascot (also usable as an avatar), `prop` = an object or product, `location` = a place.
  - `description` string — Optional context notes (what it is, when to use it). Do NOT describe appearance; the photo decides how the element looks.
  - `imageUrl` string — Public URL of the reference photo (JPEG, PNG, or WebP, max 25MB). We download and store it. Use this OR imageAssetId.
  - `imageAssetId` string, uuid — An asset from `POST /uploads` with purpose `element-image`. Use this OR imageUrl.

## Response `200`

OK

- object
  - `id` string, uuid, required — Element ID. For characters, this is also a valid `avatarId` for avatar videos.
  - `name` string, required — Element name.
  - `handle` string, required — Mention this element in a video script as `@handle` to put it in the video.
  - `type` 'character' | 'prop' | 'location', required — `character` = a person or mascot, `prop` = an object or product, `location` = a place.
  - `description` string, nullable, required — Optional context notes. Appearance always comes from the photo, not from this text.
  - `custom` boolean, required — True for elements you created, false for built-in ones.
  - `previewImageUrl` string, nullable, required — The reference photo.

## Other responses

- `401` — 401
- `402` — 402
- `403` — 403

---

[API](https://skmtc.net/aituber/apis/aituber-api.md) · [All operations](https://skmtc.net/aituber/apis/aituber-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/aituber/aituber-api/revisions/35448566f143/schema)
