Create an avatar

Upload a zip with a manifest, an image and a voice sample, and get back a fully built, ready-to-chat avatar.

Everything a person can do in Studio → Create avatar — upload a face, a voice sample, write a persona, attach knowledge files — is also one API call. The avatar that comes back is identical to one built in the UI: it shows up in Manage and can be used with POST /v1/session the same way.

Create a key with the right scope

Avatar management needs a key with the avatars:write scope; the default sessions scope is not enough. Add billing:write too if the manifest will carry a sponsor block. The key must be account-wide — an avatar-scoped key can update the one avatar it is scoped to, but never create or delete. See API keys.

Build the zip

snippet
my-avatar.zip
├── avatar.json          # manifest (required)
├── image/portrait.jpg   # exactly one image (jpg/png/webp ≤10 MB)
├── voice/sample.wav     # exactly one sample (mp3/wav/m4a/aac/ogg/flac/opus/webm, 10–60 s, ≤12 MB)
├── prompt/prompt.txt    # the scenario, free text (≤10,000 chars) -- or use persona.scenario
└── knowledge/           # optional, ≤20 files: pdf/docx/doc/txt/md/html/csv ≤50 MB each

The image should show the whole head with some margin around it; a face that fills the frame edge to edge fails the preview stage. The voice sample is checked server-side for clean, audible speech — not silence or a pure tone.

avatar.json:

snippet
{
  "schemaVersion": 1,
  "name": "Grand Valley Concierge",
  "description": "Friendly resort concierge",
  "language": "en",
  "visibility": "private",
  "persona": {
    "preferredAlias": "Val",
    "personality": "A warm, endlessly patient concierge who knows the resort inside out and keeps every answer practical.",
    "greeting": "Hi, I'm Val — how can I help?",
    "selfIntroduction": "I'm Val, the concierge for Grand Valley resort...",
    "guardrails": ["Never quote prices that aren't in the knowledge base"],
    "conversationalHabits": {
      "CONVERSATIONAL_HABIT_ENGAGEMENT": "CONVERSATIONAL_HABIT_SCALE_MEDIUM"
    }
  },
  "knowledge": { "descriptions": { "pricing.pdf": "2026 rate card" } },
  "previewMessage": "Hello!"
}
FieldRequiredNotes
nameyesThe project name shown in Studio (1–100 chars).
visibilitynoprivate or unlisted at create time. public requires a PATCH once the avatar is ready.
languagenoen, zh-TW or ja.
persona.preferredAliasnoThe name the avatar goes by in conversation.
persona.personalitynoThe main character description — who the avatar is. Up to 10,000 chars.
persona.scenarionoWhat the avatar is doing with the visitor. JSON alternative to prompt/prompt.txt — providing both is rejected.
persona.selfIntroductionno51–2000 chars, used verbatim; derived from personality when absent.
persona.greetingnoThe avatar's opening line, ≤500 chars.
persona.guardrailsnoUp to 20 entries, ≤500 chars each, used verbatim.
knowledge.descriptionsnoMaps a filename in knowledge/ to a short description. Up to 20 files.
sponsorno{ microcredits, maxPerSession } — funds the avatar's budget at creation. Needs billing:write. See Sponsored access.

Upload it

snippet
curl -X POST "https://api.atmanity.us/v1/avatars" \
  -H "X-Api-Key: $ATMEE_API_KEY" \
  -F "file=@my-avatar.zip"
snippet
{
  "avatarId": "56cc8fdd-ba78-4d48-a210-16cf80c3f5f5",
  "status": "building",
  "statusUrl": "/v1/avatars/56cc8fdd-ba78-4d48-a210-16cf80c3f5f5"
}

A 202 means the build has started. A malformed zip or manifest answers 400 with an error of invalid_zip or invalid_manifest and a message naming the problem; the full list of codes is in the Reference.

Use https://staging.atmanity.us with a staging key while you develop — keys are not interchangeable between environments, same as /v1/session.

Poll until it's ready

snippet
curl "https://api.atmanity.us/v1/avatars/56cc8fdd-ba78-4d48-a210-16cf80c3f5f5" \
  -H "X-Api-Key: $ATMEE_API_KEY"
snippet
{
  "id": "56cc8fdd-ba78-4d48-a210-16cf80c3f5f5",
  "name": "Grand Valley Concierge",
  "status": "ready",
  "readyToChat": true,
  "moderationState": "clean",
  "visibility": "private",
  "stages": {
    "appearance": { "status": "completed" },
    "voice": { "status": "completed" },
    "persona": { "status": "completed" },
    "knowledge": { "status": "completed" },
    "previews": { "status": "completed" }
  }
}

status is buildingready (or failed / moderation_hold). Each stage under stages is independently waitingpendingprocessingcompleted (or failed, with a userFeedback message you can show verbatim). A clean build typically finishes in under a minute; poll every few seconds rather than long-polling.

Once readyToChat is true, start a session with POST /v1/session using the id as avatarId, exactly as in the Quickstart.

Update it afterwards

Text changes — name, description, visibility, language, preview message and every persona field — go through PATCH /v1/avatars/{avatarId}. A new image, voice sample or knowledge set is a PUT to /appearance, /voice or /knowledge; only the affected build stages re-run, and the avatar answers building again until they finish. DELETE /v1/avatars/{avatarId} removes it.

Next steps

Create an avatar — Atmee Docs