Start Session
Starts an interactive avatar session with a session token. Use livekit.url and livekit.token from the response to connect to real-time video streaming.
What is LiveKit?
LiveKit is a WebRTC-based real-time video streaming stack. After Start Session returns livekit.url, livekit.token, and room_name, the client calls something like room.connect(url, token) to join the LiveKit server. Once connected, the avatar’s video, audio, and data channels stream in real time for a conversational experience.
POST /api/v2/sessions/start
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {session_token} |
| Content-Type | application/json |
Body
| Field | Type | Required | Description |
|---|---|---|---|
| avatar_id | string | required | Avatar / model ID |
| avatar_persona | object | optional | Persona and LLM overrides. If omitted, server defaults apply: English (en), OpenAI, gpt-4.1-nano. |
| avatar_persona.language | string | optional | e.g. en, ko, en-US |
| avatar_persona.llm_configurations | object | optional | LLM provider/model settings. Server defaults apply if omitted. |
| avatar_persona.llm_configurations.provider | string | optional | e.g. openai, anthropic, google, custom |
| avatar_persona.llm_configurations.model | string | optional | Model ID |
| avatar_persona.llm_configurations.temperature | number | optional | Temperature forwarded to the LLM |
| avatar_persona.llm_configurations.custom_settings | object | optional | greeting_text, system_prompt overrides |
| avatar_persona.llm_configurations.custom_http | object | optional | Used only when provider is "custom". Requires endpoint or url. |
| max_session_duration | integer | optional | Maximum session length in minutes. Must be within your Plan limit. |
| lip_audio_mode | string | optional | llm_tts or external_pcm. If omitted, the default audio behavior applies. |
If max_session_duration is omitted, your Account subscription limit applies. max_session_numbers is not accepted in the request body; it is determined by your subscription plan.
Custom HTTP LLM
Use avatar_persona.llm_configurations.provider: "custom" with custom_http when you want the session to use your own HTTP LLM endpoint.
| Field | Type | Description |
|---|---|---|
| endpoint | string | Full POST URL for your custom LLM server |
| url | string | Alias for endpoint; mapped to endpoint if endpoint is omitted |
| connect_timeout_sec, read_timeout_sec, timeout_sec | number | Connection/read timeouts in seconds |
| max_messages, max_chars, max_buffer_chars | number | Conversation trimming and text flush limits |
| http_error_message | string | Message prefix yielded when the upstream returns HTTP 4xx/5xx |
| stream_connect_retries, stream_connect_retry_delay_sec | number | Retry settings before the first SSE line or response body |
| headers, extra_headers | object | Static headers. Prefer one; if both are present, headers is used. |
| auth_plugins | array | Auth plugin objects |
| stream | boolean | Defaults to true for SSE. Use false for a single JSON response. |
| api_preset | string | openai_compatible (default), anthropic_messages, or gemini_generate_content |
api_preset reference formats:
openai_compatible: OpenAI-compatible Chat Completions formatanthropic_messages: Anthropic Messages API formatgemini_generate_content: Gemini GenerateContent format
api_preset selects the HTTP payload shape and response parser used for your custom endpoint. It does not mean every option in the provider's official API is supported. If you need provider-specific features beyond the supported shape, put them behind your own HTTP gateway and return one of the supported response formats.
| Preset | Best for | Streaming response | Non-streaming response |
|---|---|---|---|
openai_compatible | OpenAI-compatible Chat Completions endpoints and most LLM gateways | SSE chunks with text deltas | One JSON body with text in choices[0].message.content |
anthropic_messages | Anthropic Messages-compatible endpoints | SSE events with text deltas | One JSON body with text blocks in content |
gemini_generate_content | Gemini GenerateContent-compatible endpoints | SSE response from streamGenerateContent | One JSON body from generateContent |
For protocol details, supported customization, and socket/WebSocket limitations, see Custom HTTP LLM.
Behavior notes:
api_presetdefaults toopenai_compatible. Useanthropic_messagesfor Anthropic Messages API payloads andgemini_generate_contentfor Gemini GenerateContent payloads.- When
api_presetisanthropic_messages,modelis required. streamdefaults totrueand expects SSE. Setstream: falseonly when the upstream returns one JSON response; foropenai_compatible, text is read fromchoices[0].message.content.- Header merge order is default headers (
Content-Type,Accept) →headers/extra_headers→auth_plugins; later values override earlier values. - Default timing values are
connect_timeout_sec: 10,read_timeout_sec: 120,stream_connect_retries: 1, andstream_connect_retry_delay_sec: 0.4. - For production, prefer server-side secret assembly with
auth_pluginsor environment-backed headers instead of accepting raw API keys from untrusted clients.
Greeting / first utterance
If custom_settings.greeting_text is present and non-empty after trim, the service automatically sends one server-side chat message immediately after Start Session succeeds.
- Message:
[FIRST_MESSAGE]+ trimmedgreeting_text - Server-sent Talk message type:
first_message
Tip: The text appended after [FIRST_MESSAGE] is spoken by the avatar as-is. You can use this when you already have the exact text the avatar should say and want to inject that response directly.
When lip_audio_mode is external_pcm, the service does not send this automatic first message.
Examples
Basic session
- cURL
- Node.js
- Python
curl https://ai-streamer.deepbrain.io/api/v2/sessions/start \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${SESSION_TOKEN}" \
-d '{
"avatar_id": "${YOUR_AVATAR_ID}"
}'
import axios from "axios";
const sessionToken = "${SESSION_TOKEN}";
axios
.post(
"https://ai-streamer.deepbrain.io/api/v2/sessions/start",
{
avatar_id: "${YOUR_AVATAR_ID}",
},
{
headers: {
Authorization: `Bearer ${sessionToken}`,
"Content-Type": "application/json",
},
},
)
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.error(error);
});
import requests
url = 'https://ai-streamer.deepbrain.io/api/v2/sessions/start'
session_token = '${SESSION_TOKEN}'
headers = {
'Authorization': f'Bearer {session_token}',
'Content-Type': 'application/json'
}
body = {
'avatar_id': '${YOUR_AVATAR_ID}'
}
response = requests.post(url, headers=headers, json=body)
print(response.json())
With custom LLM
Connect a custom HTTP LLM endpoint.
- cURL
- Node.js
- Python
curl https://ai-streamer.deepbrain.io/api/v2/sessions/start \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${SESSION_TOKEN}" \
-d '{
"avatar_id": "${YOUR_AVATAR_ID}",
"avatar_persona": {
"language": "en",
"llm_configurations": {
"provider": "custom",
"model": "my-llm-model",
"custom_settings": {
"system_prompt": "You are a helpful assistant.",
"greeting_text": "Hello! How can I help you today?"
},
"custom_http": {
"endpoint": "https://your-llm-backend.example.com/v1/chat/completions",
"api_preset": "openai_compatible",
"stream": true,
"read_timeout_sec": 180,
"headers": {
"Authorization": "Bearer ${YOUR_LLM_API_KEY}"
}
}
}
}
}'
import axios from "axios";
const sessionToken = "${SESSION_TOKEN}";
axios
.post(
"https://ai-streamer.deepbrain.io/api/v2/sessions/start",
{
avatar_id: "${YOUR_AVATAR_ID}",
avatar_persona: {
language: "en",
llm_configurations: {
provider: "custom",
model: "my-llm-model",
custom_settings: {
system_prompt: "You are a helpful assistant.",
greeting_text: "Hello! How can I help you today?",
},
custom_http: {
endpoint:
"https://your-llm-backend.example.com/v1/chat/completions",
api_preset: "openai_compatible",
stream: true,
read_timeout_sec: 180,
headers: {
Authorization: "Bearer ${YOUR_LLM_API_KEY}",
},
},
},
},
},
{
headers: {
Authorization: `Bearer ${sessionToken}`,
"Content-Type": "application/json",
},
},
)
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.error(error);
});
import requests
url = 'https://ai-streamer.deepbrain.io/api/v2/sessions/start'
session_token = '${SESSION_TOKEN}'
headers = {
'Authorization': f'Bearer {session_token}',
'Content-Type': 'application/json'
}
body = {
'avatar_id': '${YOUR_AVATAR_ID}',
'avatar_persona': {
'language': 'en',
'llm_configurations': {
'provider': 'custom',
'model': 'my-llm-model',
'custom_settings': {
'system_prompt': 'You are a helpful assistant.',
'greeting_text': 'Hello! How can I help you today?',
},
'custom_http': {
'endpoint': 'https://your-llm-backend.example.com/v1/chat/completions',
'api_preset': 'openai_compatible',
'stream': True,
'read_timeout_sec': 180,
'headers': {
'Authorization': 'Bearer ${YOUR_LLM_API_KEY}',
},
},
},
},
}
response = requests.post(url, headers=headers, json=body)
print(response.json())
Success (201, code: 1000)
{
"code": 1000,
"data": {
"session_id": "${SESSION_ID}",
"max_session_duration": 20,
"max_session_numbers": 10,
"use_server_ready": true,
"livekit": {
"url": "wss://your-livekit-host",
"room_name": "room-…",
"token": "${LIVEKIT_ACCESS_TOKEN}"
}
},
"message": "Session created successfully"
}
When the request includes lip_audio_mode: "external_pcm", the response data also includes lip_audio for the LiveKit byte stream topic, PCM format, and segment behavior. If lip_audio_mode is omitted or llm_tts, lip_audio is omitted.
use_server_ready is a client coordination flag for LiveKit server-side readiness; it is currently returned as true for V2 starts.
Next step
After Start Session, connect to LiveKit with livekit.url and livekit.token to stream the avatar’s video and audio in real time. If the session stays idle without user messages, call the Session Keep-Alive API periodically.