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

# Characters API

A Character stores reusable configuration within a workspace. Saving validates the configuration, performs content checks, and may rehost source images. Use its returned `character_id` with [Create Session from Character](/streaming-avatar/api-references/sessions) to start a session.

**Response envelope.** REST responses are wrapped in `{code, message, data}`: `code = 0` means success. Field descriptions below refer to fields inside `data`.

## 1. Create Character

### Automatic closure

A Character can store top-level `auto_close`, using the direct Create Session schema. Rules take effect in newly created sessions. Preserve this field when reading and updating a character. See [Automatic session closure](/streaming-avatar/integrate/sessions).

Stores a Create Session JSON as a workspace-level character.

POST `/v1/characters`

### Body Parameters

Send the session configuration plus a display `name`. The read endpoint returns the saved configuration; source image URLs may be rehosted during saving. Saving a character does not start a session.

**name: string**

Display name for lists.

**model: string; required to start a session**

Model id. Use `vivix-a1-stream`, or `vivix-a1-stream-lite` for the lighter variant. See [Models](https://platform.vivix.ai/doc/overview/models).

**session: optional object**

Initial mutable session state: mode, active avatar, and the source image used for video. Optional — with a single avatar the defaults below already resolve. Change these values after the session starts with `session.update` on the control channel.

**`session.mode`: optional string**

`text_chat` or `video_avatar`. Defaults to `video_avatar`. `text_chat` returns text only; `video_avatar` returns avatar video with generated speech and text events.

**`session.active_avatar_id`: optional string**

Avatar whose instructions are active when the session starts; in `video_avatar` mode it is also the avatar rendered in the video. Selected automatically when the session has exactly one avatar, and required when it has several.

**`session.source_image_id`: optional string**

Source image used for avatar video in `video_avatar` mode. If omitted, uses the active avatar’s `visual.default_source_image_id`. If no default is set and that avatar has exactly one source image, it is selected automatically. In video mode, the request fails if no usable image can be resolved.

**output: object**

Create-time avatar video output settings. Required for `video_avatar` mode and ignored in `text_chat` mode. See [output](/streaming-avatar/character/spoken-instructions).

**`output.aspect_ratio`: optional string**

Avatar video aspect ratio, such as `9:16`, `1:1`, or `16:9`.

**`output.resolution`: optional string**

Avatar video resolution. Supported values are `480p` and `720p`.

**`pipeline_config`: optional object**

Session-wide ASR, TTS, LLM, and motion settings. Omit overrides to use platform behavior. Use `tts_config` for the voice and `avatars[].instructions` for identity and response style. `motion_enhanced` and `motion_planner` are optional advanced overrides. These settings are fixed when a session is created.

**`pipeline_config.tts_config`: object**

`tts_config` configures speech synthesis for all avatars in this session and takes precedence over `avatars[].voice`. When supplied, it requires `tts_voice_id`. For Qwen Audio built-in voices, you can omit `tts_provider` and `tts_model_id`. For a Vivix cloned voice, put its returned `voice_id` in `tts_voice_id`; the platform resolves the associated speech service. To use another built-in service, provide a matching `provider`, model, and voice ID. See the Pipeline configuration fields below for the schema, [Text to speech](/streaming-avatar/integrate/speech-synthesis) for examples, and [Choose a voice](/streaming-avatar/character/voice) for built-in voices.

**`pipeline_config.motion_enhanced`: optional object**

`prompt` drives the motion generated while the avatar is speaking. See [motion\_enhanced](/streaming-avatar/character/speaking-motion).

**`pipeline_config.motion_planner`: optional object**

`prompt` drives listening (idle) motion. The key is `motion_planner`, not `idle_motion`. See [motion\_planner](/streaming-avatar/character/listening-motion).

**`pipeline_config.asr_config`: optional object**

Advanced override. Omit it to use the platform default, `doubao`. Set `provider` (`doubao` for multilingual, or `nova-3` for English-only) and optional `language`. See [`asr_config`](/streaming-avatar/integrate/speech-recognition).

**`pipeline_config.llm_config`: optional object**

`llm_config` · optional object. Set `llm_base_url` and `llm_model` for a custom service, or override only generation parameters. See [Text model configuration](/streaming-avatar/integrate/dialogue-model) for field types and examples.

**avatars: object\[]**

Avatars available in the session. Must not be empty, and `avatar_id` values must not repeat.

**`avatars.avatar_id`: string**

Identifier, unique within the session. Must not be empty.

**`avatars.instructions`: optional string**

Role, speaking style, and response guidance for this avatar; they apply while this avatar is active.

**`avatars.voice`: optional object**

Per-avatar voice. Use it only when `pipeline_config.tts_config` is omitted and avatars need different voices; `provider`, `provider_voice_id`, and `model` are then all required, with optional `speed`. The fields mirror [`tts_config`](/streaming-avatar/integrate/speech-synthesis).

**`avatars.visual`: object**

Video appearance. A video avatar needs a usable source image. Each entry has a unique `source_image_id`, an accessible `url`, and must include `media_type`. It may include `description`. The optional description describes the person, pose, and scene. Optional settings include `default_source_image_id`, `instructions`, and cinematic cuts. See [Set the appearance](/streaming-avatar/character/first-image).

**conversation: optional object**

Session-level conversation defaults: `tools`, `turn_detection`, and `input_audio_transcription`. See [conversation](/streaming-avatar/character/spoken-instructions).

**`max_duration_seconds`: optional int32**

Maximum session duration in seconds. If omitted, the default session length applies. An explicit value must be greater than `3` (minimum 4).

### Response Fields

Create, GET, and PUT all return the full character: metadata plus the entire stored config.

**`character_id`: string**

Character id, shaped like `chr_…`. Use it to start a session from [Sessions API](/streaming-avatar/api-references/sessions).

**name: string**

Display name.

**created\_at: timestamp**

UTC, formatted as `YYYY-MM-DDTHH:MM:SSZ`.

**updated\_at: timestamp**

UTC, formatted as `YYYY-MM-DDTHH:MM:SSZ`.

**stored config: object**

The saved configuration fields are returned alongside metadata under `data`. `name` is stored as metadata; `character_id` and `idempotency_key` are not saved as session configuration. Source image URLs may be rewritten during saving.

### Error Cases

**Missing `name`, or invalid JSON.** · API error code: `20004 invalid parameter`

**`avatars` is empty or missing.** · API error code: `20012 avatars is required`

**Invalid `avatars` (missing `avatar_id`, duplicate ids, or `active_avatar_id` does not match).** · API error code: `20013 invalid avatars`

**`video_avatar` (or default mode) is missing `output`.** · API error code: `20014 output is required for video_avatar mode`

**Content rejected by moderation.** · API error code: `30001 content rejected by moderation`

**The API key is missing or invalid.** · API error code: `10001 missing api key` or `10003 invalid api key`

**The request exceeded the API key rate limit.** · API error code: `10008 API rate limit exceeded`

Request

```bash wrap theme={null}
curl -X POST https://api.vivix.ai/v1/characters \
  -H "Authorization: Bearer $VIVIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Studio Host",
  "model": "vivix-a1-stream",
  "output": {
    "aspect_ratio": "9:16",
    "resolution": "720p"
  },
  "pipeline_config": {
    "tts_config": {
      "tts_provider": "qwen-audio-3.0-tts-flash_ws",
      "tts_voice_id": "longanhuan_v3.6",
      "tts_model_id": "qwen-audio-3.0-tts-flash"
    }
  },
  "avatars": [
    {
      "avatar_id": "host_a",
      "instructions": "You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.",
      "visual": {
        "default_source_image_id": "front",
        "source_images": [
          {
            "source_image_id": "front",
            "url": "https://cdn.example.com/avatars/host-a-front.png",
            "description": "A woman facing the camera in a brightly lit studio, front view.",
            "media_type": "image/png"
          }
        ]
      }
    }
  ]
}'
```

Response

```json wrap theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
    "name": "Studio Host",
    "created_at": "2026-08-19T10:00:00Z",
    "updated_at": "2026-08-19T10:00:00Z",
    "model": "vivix-a1-stream",
    "output": {
      "aspect_ratio": "9:16",
      "resolution": "720p"
    },
    "pipeline_config": {
      "tts_config": {
        "tts_provider": "qwen-audio-3.0-tts-flash_ws",
        "tts_voice_id": "longanhuan_v3.6",
        "tts_model_id": "qwen-audio-3.0-tts-flash"
      }
    },
    "avatars": [
      {
        "avatar_id": "host_a",
        "instructions": "You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.",
        "visual": {
          "default_source_image_id": "front",
          "source_images": [
            {
              "source_image_id": "front",
              "url": "https://cdn.example.com/avatars/host-a-front.png",
              "description": "A woman facing the camera in a brightly lit studio, front view.",
              "media_type": "image/png"
            }
          ]
        }
      }
    ]
  }
}
```

## 2. List Characters

Lists undeleted characters in the current workspace, newest first. The list does not return the full `avatars` / `pipeline_config`; it returns summary fields only.

GET `/v1/characters`

### Query Parameters

**page\_size: optional integer**

Page size. Defaults to 50; maximum 200.

**page\_token: optional string**

The `next_page_token` from the previous response. An invalid token returns `20004`.

### Response Fields

**items: array**

Character summaries, newest first.

**`items[].character_id`: string**

Character id.

**`items[].name`: string**

Display name.

**`items[].model`** · string. Model ID saved with this character.

The `model` from the stored config.

**`items[].resolution`: string**

`output.resolution` from the stored config, when present.

**`items[].created_at`: timestamp**

UTC.

**`items[].updated_at`: timestamp**

UTC.

**next\_page\_token: string**

Cursor for the next page. Empty string when there is no next page.

Request

```bash theme={null}
curl "https://api.vivix.ai/v1/characters?page_size=50" \
  -H "Authorization: Bearer $VIVIX_API_KEY"
```

Response

```json theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "items": [
      {
        "character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
        "name": "Studio Host",
        "model": "vivix-a1-stream",
        "resolution": "720p",
        "created_at": "2026-08-19T10:00:00Z",
        "updated_at": "2026-08-19T10:00:00Z"
      }
    ],
    "next_page_token": ""
  }
}
```

## 3. Get Character

Returns the full character (metadata plus the entire stored config). Same shape as Create Character.

GET `/v1/characters/{character_id}`

### Path Parameters

**`character_id`: string**

Character id.

### Error Cases

**The character does not exist, is deleted, or is not in the current workspace.** · API error code: `20005 not found`

Request

```bash wrap theme={null}
curl https://api.vivix.ai/v1/characters/chr_a1b2c3d4e5f6789012345678abcdef01 \
  -H "Authorization: Bearer $VIVIX_API_KEY"
```

Response

```json wrap theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
    "name": "Studio Host",
    "created_at": "2026-08-19T10:00:00Z",
    "updated_at": "2026-08-19T10:00:00Z",
    "model": "vivix-a1-stream",
    "output": {
      "aspect_ratio": "9:16",
      "resolution": "720p"
    },
    "pipeline_config": {
      "tts_config": {
        "tts_provider": "qwen-audio-3.0-tts-flash_ws",
        "tts_voice_id": "longanhuan_v3.6",
        "tts_model_id": "qwen-audio-3.0-tts-flash"
      }
    },
    "avatars": [
      {
        "avatar_id": "host_a",
        "instructions": "You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.",
        "visual": {
          "default_source_image_id": "front",
          "source_images": [
            {
              "source_image_id": "front",
              "url": "https://cdn.example.com/avatars/host-a-front.png",
              "description": "A woman facing the camera in a brightly lit studio, front view.",
              "media_type": "image/png"
            }
          ]
        }
      }
    ]
  }
}
```

## 4. Update Character

**PUT replaces the whole record; it is not PATCH.** The body matches create (including `name`). Keys omitted from the request are deleted from the stored config. The success `data` is the character after the write, so you can check what was stored.

PUT `/v1/characters/{character_id}`

### Path Parameters

**`character_id`: string**

Character id to replace.

Body parameters match Create Character. Validation and moderation rules are the same.

### Error Cases

**The character does not exist, is deleted, or is not in the current workspace.** · API error code: `20005 not found`

**Other validation failures.** · API error code: Same as Create Character.

Request

```bash wrap theme={null}
curl -X PUT https://api.vivix.ai/v1/characters/chr_a1b2c3d4e5f6789012345678abcdef01 \
  -H "Authorization: Bearer $VIVIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Studio Host v2",
  "model": "vivix-a1-stream",
  "output": {
    "aspect_ratio": "9:16",
    "resolution": "720p"
  },
  "pipeline_config": {
    "tts_config": {
      "tts_provider": "qwen-audio-3.0-tts-flash_ws",
      "tts_voice_id": "longanhuan_v3.6",
      "tts_model_id": "qwen-audio-3.0-tts-flash"
    }
  },
  "avatars": [
    {
      "avatar_id": "host_a",
      "instructions": "You are Host A, a warm livestream host.",
      "visual": {
        "default_source_image_id": "front",
        "source_images": [
          {
            "source_image_id": "front",
            "url": "https://cdn.example.com/avatars/host-a-front.png",
            "description": "A woman facing the camera in a brightly lit studio, front view.",
            "media_type": "image/png"
          }
        ]
      }
    }
  ]
}'
```

Response

```json wrap theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
    "name": "Studio Host v2",
    "created_at": "2026-08-19T10:00:00Z",
    "updated_at": "2026-08-19T11:00:00Z",
    "model": "vivix-a1-stream",
    "output": {
      "aspect_ratio": "9:16",
      "resolution": "720p"
    },
    "pipeline_config": {
      "tts_config": {
        "tts_provider": "qwen-audio-3.0-tts-flash_ws",
        "tts_voice_id": "longanhuan_v3.6",
        "tts_model_id": "qwen-audio-3.0-tts-flash"
      }
    },
    "avatars": [
      {
        "avatar_id": "host_a",
        "instructions": "You are Host A, a warm livestream host.",
        "visual": {
          "default_source_image_id": "front",
          "source_images": [
            {
              "source_image_id": "front",
              "url": "https://cdn.example.com/avatars/host-a-front.png",
              "description": "A woman facing the camera in a brightly lit studio, front view.",
              "media_type": "image/png"
            }
          ]
        }
      }
    ]
  }
}
```

## 5. Delete Character

Soft-deletes the character. In-progress live sessions are not interrupted. A deleted character cannot be used to create a new session.

DELETE `/v1/characters/{character_id}`

### Path Parameters

**`character_id`: string**

Character id to delete.

### Response Fields

**`character_id`: string**

Id of the deleted character.

**status: string**

Always `deleted`.

### Error Cases

**The character does not exist, is deleted, or is not in the current workspace.** · API error code: `20005 not found`

Request

```bash wrap theme={null}
curl -X DELETE https://api.vivix.ai/v1/characters/chr_a1b2c3d4e5f6789012345678abcdef01 \
  -H "Authorization: Bearer $VIVIX_API_KEY"
```

Response

```json theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
    "status": "deleted"
  }
}
```

### Pipeline configuration fields

These fields belong in the creation request’s `pipeline_config` object. Merge them with the existing configuration when creating a new session. They cannot be changed through `session.update`.

**`tag_audio_enabled`** · boolean · Optional; defaults to false. Enables faster audio output for an eligible first short speech segment of the response, not emotion tags. Supply a boolean, not a string. See [opening acknowledgements](/streaming-avatar/interaction/acknowledgement).

### `asr_config`

**`provider`** · string · Required when `asr_config` is supplied. Common values are `doubao` and nova-3. The platform supplies a default service when the whole object is omitted, but not when only `language` is provided.

**`language`** · string · Optional. Examples: `zh-CN` or `en-US` for Doubao; en for Nova. Controls recognition `language`, not the reply language.

**`eou_timeout_ms`** · string · Optional end-of-utterance judge timeout, for example "1500". Not a fixed silence length or total response latency.

```json theme={null}
{
  "pipeline_config": {
    "asr_config": {
      "provider": "doubao",
      "language": "zh-CN"
    }
  }
}
```

[Speech recognition and transcript events](/streaming-avatar/integrate/speech-recognition)

### `llm_config`

**`llm_backend`** · string · Optional; only `openai` is supported.

**`llm_base_url`** · string · Optional OpenAI-compatible endpoint. Supply with llm\_model for a custom service; omit when only tuning generation settings.

**`llm_model`** · string · Optional custom model name.

**`llm_api_key`** · string · Optional service credential. Keep private credentials out of browser code and public configuration.

**`llm_temperature`** · number · Optional generation temperature; use the range supported by the model.

**`llm_max_output_tokens`** · integer · Optional generated-token limit, not a word count.

**`llm_extra_payload`** · string · Optional JSON-encoded object string; do not supply a nested object.

```json theme={null}
{
  "pipeline_config": {
    "llm_config": {
      "llm_temperature": 0.4,
      "llm_max_output_tokens": 256,
      "llm_extra_payload": "{\"top_p\":0.9}"
    }
  }
}
```

[Connect a custom text service](/streaming-avatar/integrate/dialogue-model)

### `tts_config`

**`tts_voice_id`** · string · Required nonempty `provider` voice ID or Vivix cloned voice\_id.

**`tts_provider`** · string · Optional. For built-in Qwen Audio voices, defaults to `qwen-audio-3.0-tts-flash_ws`. A Vivix cloned `voice_id` resolves to its associated speech service. Set the matching value for other services.

**`tts_model_id`** · string · Optional. For built-in Qwen Audio voices, defaults to `qwen-audio-3.0-tts-flash`. A Vivix cloned `voice_id` resolves to its associated model. Set the matching value for other services.

**`tts_endpoint`** · string · Optional endpoint override when nonempty. Not needed for built-in voices.

**`tts_api_key`** · string · Optional `provider` credential when nonempty. Built-in voices need no separate key.

**`payload`** · object · Optional speech-service extensions; arbitrary `provider` parameters are not guaranteed to take effect. Do not duplicate reserved authentication or routing fields here.

```json theme={null}
{
  "pipeline_config": {
    "tag_audio_enabled": false,
    "tts_config": {
      "tts_voice_id": "longanhuan_v3.6"
    }
  }
}
```

[TTS configuration and supported service combinations](/streaming-avatar/integrate/speech-synthesis)

### Source image media type

`avatars[].visual.source_images[].media_type` is required and must start with `image/`, for example `image/png` or `image/jpeg`. Use the actual image format, not the video output format.

### Continue reading

[Character instructions](/streaming-avatar/character/spoken-instructions) · [Speech recognition](/streaming-avatar/integrate/speech-recognition) · [Text model](/streaming-avatar/integrate/dialogue-model) · [Text to speech](/streaming-avatar/integrate/speech-synthesis) · [Opening acknowledgements](/streaming-avatar/interaction/acknowledgement)
