curl --request POST \
--url https://api.vivix.ai/v1/characters \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"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"
}
]
}
}
]
}
'import requests
url = "https://api.vivix.ai/v1/characters"
payload = {
"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"
}
]
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
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'
}
]
}
}
]
})
};
fetch('https://api.vivix.ai/v1/characters', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vivix.ai/v1/characters",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'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'
]
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vivix.ai/v1/characters"
payload := strings.NewReader("{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vivix.ai/v1/characters")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vivix.ai/v1/characters")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"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"
}
]
}
}
]
}
}Create Character
Stores a Create Session JSON as a workspace-level character.
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.
Create, GET, and PUT all return the full character: metadata plus the entire stored config.
curl --request POST \
--url https://api.vivix.ai/v1/characters \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"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"
}
]
}
}
]
}
'import requests
url = "https://api.vivix.ai/v1/characters"
payload = {
"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"
}
]
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
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'
}
]
}
}
]
})
};
fetch('https://api.vivix.ai/v1/characters', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vivix.ai/v1/characters",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'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'
]
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vivix.ai/v1/characters"
payload := strings.NewReader("{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vivix.ai/v1/characters")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vivix.ai/v1/characters")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Studio Host\",\n \"model\": \"vivix-a1-stream\",\n \"output\": {\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\"\n },\n \"pipeline_config\": {\n \"tts_config\": {\n \"tts_provider\": \"qwen-audio-3.0-tts-flash_ws\",\n \"tts_voice_id\": \"longanhuan_v3.6\",\n \"tts_model_id\": \"qwen-audio-3.0-tts-flash\"\n }\n },\n \"avatars\": [\n {\n \"avatar_id\": \"host_a\",\n \"instructions\": \"You are Host A, a warm livestream host. Answer briefly, acknowledge corrections, and speak only the words the user should hear.\",\n \"visual\": {\n \"default_source_image_id\": \"front\",\n \"source_images\": [\n {\n \"source_image_id\": \"front\",\n \"url\": \"https://cdn.example.com/avatars/host-a-front.png\",\n \"description\": \"A woman facing the camera in a brightly lit studio, front view.\",\n \"media_type\": \"image/png\"\n }\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"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"
}
]
}
}
]
}
}Automatic closure
Automatic closure
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.Errors
Errors
{code, message, data} envelope; a non-zero code identifies the error.| Case | Error code |
|---|---|
Missing name, or invalid JSON | 20004 invalid parameter |
avatars is empty or missing | 20012 avatars is required |
Invalid avatars (missing avatar_id, duplicate ids, or active_avatar_id does not match) | 20013 invalid avatars |
video_avatar (or default mode) is missing output | 20014 output is required for video_avatar mode |
| Content rejected by moderation | 30001 content rejected by moderation |
| The API key is missing or invalid | 10001 missing api key or 10003 invalid api key |
| The request exceeded the API key rate limit | 10008 API rate limit exceeded |
Authorizations
Your Vivix API key. Keep it on your server.
Body
Display name for lists.
Avatars available in the session. Must not be empty, and avatar_id values must not repeat.
Show child attributes
Show child attributes
Optional deployment region hint. Returned back on the session object; may be empty if not provided. It does not currently affect scheduling or guarantee data residency.
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.
Show child attributes
Show child attributes
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.
Show child attributes
Show child attributes
Session-level conversation defaults: tools, turn_detection, and input_audio_transcription. See conversation.
Show child attributes
Show child attributes
Session-scoped reusable assets for response.script. Asset ids must be unique across audio, speech_text, and visual_prompts. Avatar source images stay under avatars[].visual.source_images. On the REST side the visual prompt text field is prompt; on the WSS asset.add side the same asset uses text — the two shapes differ.
Show child attributes
Show child attributes
Media delivery settings used when session.mode is video_avatar. If omitted, the media transport defaults to TRTC. It is not used for text_chat.
Show child attributes
Show child attributes
Maximum session duration in seconds. If omitted, the default session length applies. An explicit value must be greater than 3 (minimum 4).
Automatic close policy fixed when the session is created. The response returns the effective values after platform defaults are applied.
Show child attributes
Show child attributes
on or off. Send off to disable recording.
Response
Success