Agents
Agents
What an agent is, how to author and configure one, and how a conversation with it fits together from your server to your user's device.
An agent is a character you write once and your users talk to many times, by text or by voice. You describe who it is, where the conversation happens, how it speaks, what it is trying to do and what it must not do. The API holds every conversation, so each turn carries only the new message. The reply streams back as text and, if the agent speaks, as audio.
curl https://api.lumavox.ai/v1/agents \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Mira", "personality": "A patient travel guide who has lived in Lisbon for twenty years.", "environment": "A chat on a travel booking site.", "tone": "Warm and brief. Two or three sentences unless asked for more.", "goal": "Help the traveller plan their first three days.", "guardrails": "Never quote prices or make bookings.", "first_message": "Olá! Is this your first time in Lisbon?", "voice_enabled": true, "voice_config": { "voice_id": "default" } }'{ "id": "0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07", "name": "Mira", "model": "gemini-3.1-flash-lite", "version": 1, "voice_enabled": true, "first_message": "Olá! Is this your first time in Lisbon?", "first_message_generated": false, "thinking_level": null, "created_at": "2026-10-24T09:14:03.000Z", "updated_at": "2026-10-24T09:14:03.000Z"}The agent comes back with every field it has, null for each setting you left unset. The full shape is in the agents reference.
GET /v1/agents lists your agents, newest first, each with sessions, turns and last_used_at beside its settings. They come in one page, with next_cursor always null (Conventions). GET /v1/agents/{agent_id} reads one.
Who the agent is
Section titled “Who the agent is”Five prose fields describe the character. They are joined into one system instruction in a fixed order. A field you leave empty is left out entirely rather than sent blank.
| Field | What it holds |
|---|---|
personality |
Who the agent is: character, background, quirks. |
environment |
The setting the conversation takes place in. |
tone |
How it speaks: register, pacing, how much it says. |
goal |
What it is trying to achieve in the conversation. |
guardrails |
What it must not do or discuss. |
name is for you and your dashboards. It is never sent to the model.
The opening line
Section titled “The opening line”first_message is what the agent says first. With first_message_generated on, the same field is a direction instead, such as “say hello and catch up with them”. The model then writes the line fresh each time and can use what it remembers about the person. A scripted line costs nothing. A generated one is a billed model call.
Either way, the opening line is the agent’s first turn on the WebSocket. It streams and is spoken like every other reply. Opening a session does not produce it.
The agent does not greet twice. A conversation continued within a quiet period gets no fresh opening line, and the socket’s ready frame says which will happen (see The WebSocket). The quiet period is resume_greeting_after_minutes in your organisation’s defaults, else the platform’s agents.greeting.resume_after_minutes (Limits).
first_message_generated needs a first_message to act on. Turning it on with the text empty is a 422.
Switches
Section titled “Switches”| Field | What it does |
|---|---|
voice_enabled |
Replies come back as audio as well as text. A client can override it for one turn with speech on the message. |
voice_config |
The voice: voice_id from GET /v1/voices, model (eleven_flash_v2_5, the default, or eleven_multilingual_v2), sample_rate (8000, 16000, 22050, 24000 or 44100; 24000 when unset) and provider_options (stability, similarity, style, speed). eleven_v3 is refused with 422 on a speaking agent: it cannot stream over the socket. |
emotion_enabled |
Each reply reports how the agent feels. The mood arrives as a mood event and is stored on the message. It costs about six output tokens per turn. |
relation_enabled |
The agent keeps a standing relationship with each person (warmth, trust, how well they know each other) across every conversation. Read it with GET /v1/agent/relations. |
knowledge_enabled |
Whether the agent may use the knowledge assigned to it. On by default. Turning it off hides the entries without unassigning them. |
stt_config |
How a spoken turn is transcribed: language (detected per turn when unset), sample_rate of the PCM your client sends, model and mark_spoken. A client can override the first three per recording. |
model, thinking_level, thinking_summaries, max_output_tokens |
The Gemini model and how it thinks. The default model is the platform’s agents.model (Limits). |
stream_chunk_schedule |
How a streamed reply is cut into pieces for speech, smallest first, for example [60, 160, 250]. The first number decides how much text must arrive before the agent starts talking. Below about 50 characters, speech starts sooner but can stutter. |
The compaction and memory fields (compact_threshold_tokens, extract_facts_on_compact, facts_enabled, facts_scope, max_facts and the instructions) are covered in Conversations and memory.
Edit or delete an agent
Section titled “Edit or delete an agent”PATCH /v1/agents/{agent_id} is a partial update. Fields you omit are left alone, and an explicit null clears one.
curl -X PATCH https://api.lumavox.ai/v1/agents/$AGENT_ID \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tone": "Playful, and a little more talkative.", "expected_version": 1 }'- The whole agent is checked on every save. A
thinking_levelthe model refuses, a generated opening with no direction, or a speech schedule out of order is a 422 naming the problem, whichever field you changed. - Send
expected_version(theversionyou last read) to be refused with 409 if somebody else saved the agent since. Nothing is written in that case. - Conversations already open pick up the change within about a minute, from their next turn. There is nothing to reopen. That also means somebody mid-conversation is now talking to the edited agent.
DELETE /v1/agents/{agent_id} deletes the agent and every conversation with it, and answers 204 with no body. It cannot be undone.
Your plan caps how many agents your organisation holds. Creating one past the cap is a 409.
Organisation-wide defaults
Section titled “Organisation-wide defaults”GET /v1/agents/settings returns what every agent falls back to when it sets nothing of its own. The chain is the agent, then your organisation, then the built-in default. The built-in text comes back alongside each field, so you can show what leaving it empty means.
PUT /v1/agents/settings changes them. It needs agent:write. Omitted fields are left alone, and null returns one to the built-in default.
| Field | What it sets |
|---|---|
default_emotion_instruction, default_relation_instruction, default_fact_instruction, default_compact_instruction |
The instructions agents use when they set none of their own. |
default_stream_chunk_schedule |
The speech chunk schedule for agents that set none. |
resume_greeting_after_minutes |
How long a conversation must be quiet before the agent greets the person again. 0 means always greet. 15 when unset. |
resume_max_age_days |
How old a person’s last conversation may be and still be continued rather than replaced. 0 means never continue. 7 when unset. |
The response also lists moods: every mood label the API accepts. If you override the mood instruction, name these labels. The API strips a first line shaped mood: <label> <intensity> and records a mood only for a label it knows, so an instruction asking for any other shape leaves the line in the reply.
A change reaches open conversations within about a minute, as an edit to an agent does. resume_greeting_after_minutes is read when a socket connects, so it applies from the next connection.
Scopes
Section titled “Scopes”| Scope | Lets an API key |
|---|---|
agent |
List and read agents and the defaults, manage end users, read and search knowledge, read tools. |
agent:write |
Create, edit and delete agents, set the defaults, write knowledge and tools. |
tokens |
Mint, list and revoke ephemeral keys. |
An API key cannot talk to an agent. Conversations run only on an end user’s ephemeral key: an API key gets 403 on /v1/agent/* and close code 4002 on the socket.
How a conversation fits together
Section titled “How a conversation fits together”- Your server finds or creates the person.
POST /v1/end-userswith your ownexternal_idreturns the same end user every time. See End users and their keys. - Your server mints an ephemeral key for them.
POST /v1/ephemeral-keyswith the end user and acredit_limit_micros. Hand only the token to their device. Your API key never leaves your server. - The device opens a session.
POST /v1/agent/sessionswith the token continues the person’s recent conversation with this agent, or starts a new one. See Conversations and memory. - The device connects to the socket at
wss://api.lumavox.ai/v1/agent/stream?session_id=…, with the subprotocolino.v2and anauthframe first. See The WebSocket. - The person talks. Typed or spoken turns go up; text, audio, mood and usage come back as the reply is written.
- Memory happens after the reply. Facts about the person and the relationship carry into every later conversation with any of your agents — unless an agent remembers nothing, or keeps what it learns to itself.