curl --request POST \
--url https://api.vivix.ai/v1/realtime-avatar/character-sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
"idempotency_key": "live-20260901-001"
}
'import requests
url = "https://api.vivix.ai/v1/realtime-avatar/character-sessions"
payload = {
"character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
"idempotency_key": "live-20260901-001"
}
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({
character_id: 'chr_a1b2c3d4e5f6789012345678abcdef01',
idempotency_key: 'live-20260901-001'
})
};
fetch('https://api.vivix.ai/v1/realtime-avatar/character-sessions', 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/realtime-avatar/character-sessions",
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([
'character_id' => 'chr_a1b2c3d4e5f6789012345678abcdef01',
'idempotency_key' => 'live-20260901-001'
]),
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/realtime-avatar/character-sessions"
payload := strings.NewReader("{\n \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\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/realtime-avatar/character-sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vivix.ai/v1/realtime-avatar/character-sessions")
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 \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"message": "success",
"data": {
"session_id": "avatar-session-123",
"status": "active",
"auto_close": {
"disconnected_timeout_seconds": 60,
"interaction_idle_timeout_seconds": 300
},
"region": "us-west",
"session": {
"mode": "video_avatar",
"active_avatar_id": "host_a",
"source_image_id": "front"
},
"control": {
"url": "wss://api.vivix.ai/v1/realtime-avatar/control?session_id=avatar-session-123",
"client_secret": "ctl_..."
},
"output": {
"aspect_ratio": "9:16",
"resolution": "480p",
"fps": 24
},
"assets": {
"audio": [
{
"asset_id": "welcome_jingle",
"url": "https://cdn.example.com/audio/welcome-jingle.wav",
"mime_type": "audio/wav"
}
],
"speech_text": [
{
"asset_id": "welcome_line",
"text": "Welcome back. I saved your place."
}
],
"visual_prompts": [
{
"asset_id": "wave_small",
"prompt": "smile and give a small wave"
}
]
},
"conversation": {
"instructions": "Answer as a concise livestream host.",
"tools": [
{
"type": "function",
"name": "lookup_product",
"description": "Look up product details by product id.",
"parameters": {
"type": "object",
"properties": {
"product_id": {
"type": "string"
}
},
"required": [
"product_id"
]
}
}
],
"response_defaults": {
"temperature": 0.7,
"max_output_tokens": 512
},
"turn_detection": {
"type": "server_vad",
"silence_duration_ms": 500
},
"input_audio_transcription": {
"enabled": true,
"language": "auto"
}
},
"avatars": [
{
"avatar_id": "host_a",
"instructions": "You are Host A, a warm livestream host who gives concise product-focused replies.",
"visual": {
"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"
},
{
"source_image_id": "side",
"url": "https://cdn.example.com/avatars/host-a-side.png",
"description": "The same woman in the same studio, side view.",
"media_type": "image/png"
}
],
"default_source_image_id": "front"
}
},
{
"avatar_id": "host_b",
"instructions": "You are Host B, a calm expert who gives brief technical explanations.",
"visual": {
"source_images": [
{
"source_image_id": "front",
"url": "https://cdn.example.com/avatars/host-b-front.png",
"description": "A man facing the camera in a brightly lit studio, front view.",
"media_type": "image/png"
}
],
"default_source_image_id": "front"
}
}
],
"delivery": {
"media": {
"transport": "trtc",
"trtc": {
"sdk_app_id": "1400000000",
"room_id": "avatar-session-123",
"user_id": "viewer",
"user_sig": "...",
"publisher_user_id": "publisher_xxx"
}
}
},
"model": "vivix-a1-stream",
"expires_at": "2026-07-16T10:05:00Z"
}
}Create Session from Character
Creates a Streaming Avatar session from a saved character in the current workspace. Send character_id in the JSON body, not in the URL path. The response matches Create Session.
character_id is a required string. Optional fields are idempotency_key, model, max_duration_seconds, recording_mode, output, and delivery. output and delivery are shallow-merged with the saved top-level objects. Do not send avatars in the same request.
Save changes to pipeline_config, conversation, or auto_close in the Character before starting a new session. They are not overrides on this endpoint.
curl --request POST \
--url https://api.vivix.ai/v1/realtime-avatar/character-sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
"idempotency_key": "live-20260901-001"
}
'import requests
url = "https://api.vivix.ai/v1/realtime-avatar/character-sessions"
payload = {
"character_id": "chr_a1b2c3d4e5f6789012345678abcdef01",
"idempotency_key": "live-20260901-001"
}
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({
character_id: 'chr_a1b2c3d4e5f6789012345678abcdef01',
idempotency_key: 'live-20260901-001'
})
};
fetch('https://api.vivix.ai/v1/realtime-avatar/character-sessions', 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/realtime-avatar/character-sessions",
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([
'character_id' => 'chr_a1b2c3d4e5f6789012345678abcdef01',
'idempotency_key' => 'live-20260901-001'
]),
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/realtime-avatar/character-sessions"
payload := strings.NewReader("{\n \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\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/realtime-avatar/character-sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vivix.ai/v1/realtime-avatar/character-sessions")
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 \"character_id\": \"chr_a1b2c3d4e5f6789012345678abcdef01\",\n \"idempotency_key\": \"live-20260901-001\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"message": "success",
"data": {
"session_id": "avatar-session-123",
"status": "active",
"auto_close": {
"disconnected_timeout_seconds": 60,
"interaction_idle_timeout_seconds": 300
},
"region": "us-west",
"session": {
"mode": "video_avatar",
"active_avatar_id": "host_a",
"source_image_id": "front"
},
"control": {
"url": "wss://api.vivix.ai/v1/realtime-avatar/control?session_id=avatar-session-123",
"client_secret": "ctl_..."
},
"output": {
"aspect_ratio": "9:16",
"resolution": "480p",
"fps": 24
},
"assets": {
"audio": [
{
"asset_id": "welcome_jingle",
"url": "https://cdn.example.com/audio/welcome-jingle.wav",
"mime_type": "audio/wav"
}
],
"speech_text": [
{
"asset_id": "welcome_line",
"text": "Welcome back. I saved your place."
}
],
"visual_prompts": [
{
"asset_id": "wave_small",
"prompt": "smile and give a small wave"
}
]
},
"conversation": {
"instructions": "Answer as a concise livestream host.",
"tools": [
{
"type": "function",
"name": "lookup_product",
"description": "Look up product details by product id.",
"parameters": {
"type": "object",
"properties": {
"product_id": {
"type": "string"
}
},
"required": [
"product_id"
]
}
}
],
"response_defaults": {
"temperature": 0.7,
"max_output_tokens": 512
},
"turn_detection": {
"type": "server_vad",
"silence_duration_ms": 500
},
"input_audio_transcription": {
"enabled": true,
"language": "auto"
}
},
"avatars": [
{
"avatar_id": "host_a",
"instructions": "You are Host A, a warm livestream host who gives concise product-focused replies.",
"visual": {
"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"
},
{
"source_image_id": "side",
"url": "https://cdn.example.com/avatars/host-a-side.png",
"description": "The same woman in the same studio, side view.",
"media_type": "image/png"
}
],
"default_source_image_id": "front"
}
},
{
"avatar_id": "host_b",
"instructions": "You are Host B, a calm expert who gives brief technical explanations.",
"visual": {
"source_images": [
{
"source_image_id": "front",
"url": "https://cdn.example.com/avatars/host-b-front.png",
"description": "A man facing the camera in a brightly lit studio, front view.",
"media_type": "image/png"
}
],
"default_source_image_id": "front"
}
}
],
"delivery": {
"media": {
"transport": "trtc",
"trtc": {
"sdk_app_id": "1400000000",
"room_id": "avatar-session-123",
"user_id": "viewer",
"user_sig": "...",
"publisher_user_id": "publisher_xxx"
}
}
},
"model": "vivix-a1-stream",
"expires_at": "2026-07-16T10:05:00Z"
}
}Errors
Errors
Authorizations
Your Vivix API key. Keep it on your server.
Body
Saved character to start from, shaped like chr_…. Send it in the JSON body, not in the URL path.
Client-generated key used to prevent duplicate session allocation when a create request is retried. On a 429/5xx/timeout, retry the create call with the same idempotency_key; it is safe and will not allocate a duplicate session.
Overrides the saved model.
Requested maximum session duration in seconds. If omitted, the service-configured default applies. An explicit value must be greater than 3 (minimum 4); 0 is rejected. The service may still close the session for account limits, idle timeout, failures, or maintenance.
on or off. Send off to disable recording.
Overrides the saved output; shallow-merged with the saved object.
Show child attributes
Show child attributes
Overrides the saved delivery; shallow-merged with the saved object.
Show child attributes
Show child attributes