Create a custom avatar from an image
const url = 'https://example.com/v1/avatars';const form = new FormData();form.append('image', 'example');form.append('name', 'Custom Avatar');form.append('runtime_type', 'avtr1');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/avatars \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: multipart/form-data' \ --form image=example \ --form 'name=Custom Avatar' \ --form runtime_type=avtr1Upload a portrait image to build a custom avatar. Returns the avatar in processing; poll GET /v1/avatars/{id} until it is ready (or failed). multipart/form-data: image (PNG/JPEG), name, and optional runtime_type (default avtr1).
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
Portrait image (PNG or JPEG).
Display name for the avatar.
Build stack. Default avtr1.
Responses
Section titled “ Responses ”Successful Response
Public Avatar resource returned by GET /v1/avatars and GET /v1/avatars/{id}.
object
av_… prefixed ULID.
True for platform built-in avatars (e.g. av_demo).
Runtime that serves this avatar (e.g. mock, gaussian).
Lifecycle of a custom avatar.
ready — usable for sessions.
processing — being fitted / converted.
failed — fitting failed; will not be usable without re-upload.
Example
{ "created_at": "2026-01-01T00:00:00Z", "id": "av_demo", "is_demo": true, "name": "Demo (Mock)", "object": "avatar", "runtime_type": "mock", "status": "ready"}Missing or invalid API key.
Wire format for every non-2xx public API response.
object
Concrete error returned inside ApiErrorEnvelope.error.
object
Stable machine-readable subcode (lower_snake_case). SDKs should switch on this, not message.
Human-readable summary. Not stable; do not parse.
Echo of the X-Request-Id response header for support.
Top-level error categories. Maps roughly to HTTP status.
code (a free-form lower_snake_case string on ApiError) is the
machine-readable subcode SDKs should switch on; type is the broad
category.
Example
{ "error": { "code": "transport.unsupported", "message": "transport.type=pipecat is reserved and not yet available", "param": "transport.type", "request_id": "req_01HXY5K8E7QYG3X8Z6N9R7S0VR", "type": "invalid_request" }}Unsupported image or stack.
Wire format for every non-2xx public API response.
object
Concrete error returned inside ApiErrorEnvelope.error.
object
Stable machine-readable subcode (lower_snake_case). SDKs should switch on this, not message.
Human-readable summary. Not stable; do not parse.
Echo of the X-Request-Id response header for support.
Top-level error categories. Maps roughly to HTTP status.
code (a free-form lower_snake_case string on ApiError) is the
machine-readable subcode SDKs should switch on; type is the broad
category.
Example
{ "error": { "code": "transport.unsupported", "message": "transport.type=pipecat is reserved and not yet available", "param": "transport.type", "request_id": "req_01HXY5K8E7QYG3X8Z6N9R7S0VR", "type": "invalid_request" }}