Skip to main content
POST
Create character
Save a character: a name, an image (an https URL, an upload URL, or a data URL of a JPEG or PNG), and optionally a description and a voice. The image is stored with the character for as long as it exists, unlike request inputs, which expire after 30 days. The handle is what a prompt mentions as @handle: 1 to 15 lowercase letters, digits, underscores, or dashes, starting with a letter, and unique among live characters and references. Leave it out to have one derived from the name with a short random suffix. A handle that is already in use is a 409 handle_taken; retry with another. Handles cannot be changed later. A voice clip (MP3 or WAV) goes through the same processing as a clip uploaded in the app: it is trimmed to 10 seconds and normalized, and the processed clip is what the models hear. On models that support character voices, the voice is sent whenever the character is mentioned unless the request sets use_character_voices to false. Characters created through the API are private. Publishing them happens in the app, which runs media moderation.

Authorizations

Authorization
string
header
required

An API key from Settings → API, sent as Authorization: Bearer mage_sk_…. Keys are for server-side code only.

Body

application/json
name
string
required

The display name.

Required string length: 1 - 50
image
required

The portrait: an https URL, an upload URL, or a data URL of a JPEG or PNG. Stored permanently with the character.

handle
string

The @handle prompts mention it by: 1 to 15 lowercase letters, digits, underscores, or dashes, starting with a letter. Derived from the name when omitted. Cannot be changed later.

description
string

Optional notes, for your own reference.

Maximum string length: 500
voice

Optional voice clip: an https URL, an upload URL, or a data URL of an MP3 or WAV. Trimmed to 10 seconds and normalized, like a clip uploaded in the app.

Response

The character.

id
string<uuid>
required

The character id, as DELETE /v1/characters/{character_id} takes it.

handle
string
required

Mention the character in a prompt as @handle.

name
string
required

The display name.

description
string | null
required

Your notes, or null.

image_url
string<uri>
required

The portrait.

voice_url
string<uri> | null
required

The processed voice clip, or null for a character without one.

visibility
enum<string>
required

Characters created through the API are private; publishing happens in the app.

Available options:
public,
private
created_at
string<date-time>
required

When it was created.

Last modified on September 18, 2026