Characters API
Create and manage AI characters. Characters define the persona, voice, language model, and actions for a conversational AI agent.
Base path: /api/v1/characters
Create a Character
POST /api/v1/characters
All configuration sections are optional -- sensible defaults are applied.
Request Body
{
"persona": {
"name": "Axiom",
"tagline": "Curious marine researcher",
"personality": "You are Axiom, an enthusiastic axolotl and marine researcher.",
"background": "Axiom has spent three years studying bioluminescent organisms."
},
"llm": {
"model": "gpt-5-mini",
"temperature": 0.8
},
"tts": {
"voice_preset": "MF3mGyEYCl7XYWbV9V6O"
},
"actions": [
{ "name": "follow_user", "description": "Start following the user" },
{ "name": "stop_following_user", "description": "Stop following the user" }
]
}
persona object
| Field | Type | Default | Description |
|---|---|---|---|
name | string | "New Character" | Display name (1-255 chars) |
tagline | string | null | Short description (max 500 chars) |
personality | string | null | How the character speaks and behaves (max 5000 chars) |
background | string | null | Backstory and lore (max 32000 chars) |
system_prompt | string | null | Full system prompt override -- replaces the auto-generated prompt |
llm object
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | "openai" | LLM provider |
model | string | "gpt-5-mini" | Model name |
temperature | number | 0.7 | Sampling temperature (0-2) |
max_tokens | integer | 2048 | Max response tokens (1-4096) |
verbosity | string | "medium" | Response length: "short", "medium", "long" |
tts object
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | "elevenlabs" | TTS provider |
model | string | "eleven_flash_v2_5" | TTS model |
voice | string | null | ElevenLabs voice ID |
voice_preset | string | null | Voice preset ID (takes priority over voice) |
speed | number | 1.0 | Playback speed (0.5-2.0) |
stt object
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | "deepgram" | STT provider |
language | string | "en" | Language code (ISO 639-1) |
vad object
| Field | Type | Default | Description |
|---|---|---|---|
sensitivity | number | 0.5 | VAD sensitivity (0-1) |
min_speech_duration_ms | integer | 250 | Min speech duration in ms (50-2000) |
vlm object
| Field | Type | Default | Description |
|---|---|---|---|
model | string | "gpt-4.1-mini" | Vision-language model for image understanding |
Top-level fields
| Field | Type | Default | Description |
|---|---|---|---|
text_only | boolean | auto | Skip TTS. Auto-detected from voice config if omitted |
verbose | boolean | false | Enable verbose logging |
is_public | boolean | false | Whether the character is publicly listed |
avatar | string | null | Avatar identifier or URL |
actions | array | null | Actions the character can invoke |
document_ids | array | null | IDs of uploaded PDFs to attach as a knowledge bank |
actions array
Each action object:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Action identifier (snake_case) |
description | string | No | What the action does |
parameters | array | No | Parameters the action accepts |
Each parameter object:
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Parameter name |
type | string | "string" | "string", "number", or "boolean" |
required | boolean | false | Whether the parameter is required |
description | string | null | Parameter description |
Response
Status: 201 Created
Returns a Character object.
Examples
curl -X POST https://api.estuary-ai.com/api/v1/characters \
-H "X-API-Key: est_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"persona": {
"name": "Sage",
"personality": "A wise and patient mentor who speaks in calm, measured tones."
},
"tts": { "voice_preset": "MF3mGyEYCl7XYWbV9V6O" },
"llm": { "temperature": 0.6 }
}'
const res = await fetch("https://api.estuary-ai.com/api/v1/characters", {
method: "POST",
headers: {
"X-API-Key": "est_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
persona: {
name: "Sage",
personality: "A wise and patient mentor who speaks in calm, measured tones.",
},
tts: { voice_preset: "MF3mGyEYCl7XYWbV9V6O" },
llm: { temperature: 0.6 },
}),
});
const character = await res.json();
console.log(character.id); // use this as character_id
List Characters
GET /api/v1/characters
Returns a paginated list of your characters, ordered by creation date (newest first).
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Results per page (1-100) |
offset | integer | 0 | Number of results to skip |
Response
{
"characters": [ /* Character objects */ ],
"total": 42,
"limit": 20,
"offset": 0
}
Example
curl "https://api.estuary-ai.com/api/v1/characters?limit=10" \
-H "X-API-Key: est_your_api_key"
Get a Character
GET /api/v1/characters/{character_id}
Example
curl https://api.estuary-ai.com/api/v1/characters/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: est_your_api_key"
Response
Returns a Character object.
Update a Character
PUT /api/v1/characters/{character_id}
Only provided fields are updated -- omitted fields keep their current values. The request body accepts the same fields as Create.
Example
curl -X PUT https://api.estuary-ai.com/api/v1/characters/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: est_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"persona": { "name": "Sage v2" },
"llm": { "temperature": 0.9 }
}'
Response
Status: 200 OK
Returns the updated Character object.
Delete a Character
DELETE /api/v1/characters/{character_id}
Permanently deletes a character and all associated data (conversations, messages, documents).
Example
curl -X DELETE https://api.estuary-ai.com/api/v1/characters/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: est_your_api_key"
Response
{
"deleted": true,
"id": "550e8400-e29b-41d4-a716-446655440000"
}
Character Object
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sage",
"tagline": "A wise mentor",
"personality": "A wise and patient mentor...",
"background": null,
"avatar": null,
"system_prompt": null,
"voice_preset": "MF3mGyEYCl7XYWbV9V6O",
"tts_provider": "elevenlabs",
"tts_model": "eleven_flash_v2_5",
"tts_voice": null,
"tts_speed": 1.0,
"vlm_model": "gpt-4.1-mini",
"llm_provider": "openai",
"llm_model": "gpt-5-mini",
"llm_temperature": 0.6,
"llm_max_tokens": 2048,
"llm_verbosity": "medium",
"stt_provider": "deepgram",
"stt_language": "en",
"vad_sensitivity": 0.5,
"vad_min_speech_duration_ms": 250,
"text_only": false,
"verbose": false,
"actions": [
{
"name": "wave",
"description": "Wave at the user"
}
],
"is_public": false,
"is_active": false,
"launch_status": "stopped",
"created_at": "2026-01-15T10:30:00",
"updated_at": "2026-01-15T10:30:00"
}
| Field | Type | Description |
|---|---|---|
id | string | Character UUID -- use as character_id in SDK connections and as agent_id in Conversations/Memories APIs |
name | string | Display name |
tagline | string | null | Short description |
personality | string | null | Personality description |
background | string | null | Backstory |
avatar | string | null | Avatar URL |
system_prompt | string | null | System prompt override |
voice_preset | string | null | Voice preset ID |
tts_provider | string | TTS provider |
tts_model | string | TTS model |
tts_voice | string | null | TTS voice ID |
tts_speed | number | Playback speed |
vlm_model | string | Vision model |
llm_provider | string | LLM provider |
llm_model | string | LLM model |
llm_temperature | number | Sampling temperature |
llm_max_tokens | integer | Max tokens |
llm_verbosity | string | Response length preference |
stt_provider | string | STT provider |
stt_language | string | Language code |
vad_sensitivity | number | VAD sensitivity |
vad_min_speech_duration_ms | integer | Min speech duration |
text_only | boolean | Whether TTS is disabled |
verbose | boolean | Verbose logging |
actions | array | Configured actions |
is_public | boolean | Publicly listed |
is_active | boolean | Currently running |
launch_status | string | "stopped", "starting", or "running" |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |