Skip to main content
An agent is the reusable configuration a call runs: what it says first, how it behaves, which voice, which language, and when it must stop. Calls reference an agent by ID; per-call differences go in variables. An agent runs either one prompt (system_prompt) or a graph of steps (flow). See Node-based agents for the graph. Base URL https://sandbox.voice.miraiminds.co. All endpoints require Authorization: Bearer sk_live_….

Tools

Add tools to connect your APIs before, during, or after a call. On-call HTTP tools can run synchronously or in the background, with the result returned to the voice agent when ready. See Tools for setup, conditions, secrets, callbacks, and examples.

Knowledge bases

Add knowledge to let the agent answer callers from your website, files, text and FAQ pairs. It names up to five knowledge bases and how the agent uses them. See Knowledge bases for sources, modes and limits.

Node-based agents

Add flow to run the conversation as a graph: nodes with their own instructions, and transitions the model takes when their conditions are met. With a flow, system_prompt and first_message are optional and unused, and only pre_call and post_call tools are allowed. See Node-based agents for the schema and a worked example.

The agent object

Fields

Server-set and read-only: id, object, created_at, updated_at.

Analysis

analysis reads each finished call once more, after the hangup, so it never slows the conversation. Turn it on with "enabled": true and describe what you want in prompt, success_criteria and output_schema. Add templates and the agent also picks the message template to send next, such as a WhatsApp or SMS template, and fills in its variables from the conversation. See Call analysis for every field, the result and two worked examples.

Calls from

calls_from sets the number the agent’s outbound calls and campaigns ring from when they do not choose one. Send { "pool_id": "pool_…" } for a phone pool, or { "phone_number_id": "phn_…" } for one of your numbers, never both. null unsets it. See phone numbers and pools for the order a call’s number is chosen in.

Voice

voice.language is recorded, not yet appliedThe field is validated, stored and echoed back, and it travels with the call payload. Today, though, the voice renders in the agent’s top-level language. If you set both to the same value, you get what you expect. If you set them differently, the top-level one wins until per-voice rendering ships.
Listen to the catalogue and pick a voice_id in the console. See Voices. One call can use a different voice and languages without changing the agent: send call_settings on the call, on a campaign contact, or from a pre-call tool.

Ending a call

The agent gets an end_call tool. When it fires, the agent speaks message and hangs up. If you define an explicit end_call entry in tools, that entry controls whether the tool is available, including its condition. Its builtin.enabled, builtin.message, and builtin.confirm settings override the corresponding agent settings when supplied. See Tools.
Leave confirm: true unless you are running a one-turn notification. It costs one extra turn in the rare case and prevents the far more expensive failure of hanging up on a customer mid-sentence.

Voicemail

Either way the call ends with status: voicemail and fires a call.voicemail event. Voicemail detection is available on every tier. See tiers.

Background sound

An agent speaking out of complete silence is the most obvious sign that nobody is there. background_sound plays room ambience under the voice for the whole call.
Or, with the level:
Before you turn it on, note two things:
  • The bed is in the call recording too, because it is what the callee heard. If you run your own transcription over recordings, test it first.
  • It does not touch what the agent hears. Ambience is mixed into the outbound audio only, so your callers’ speech recognition is unchanged.

Behavior

behavior sets how the agent takes turns with the caller: when it answers, and what makes it stop talking. In the console it is Agent Studio → Behavior → Interruptions, with the Adaptive interruptions switch at the top.

Adaptive interruptions

With adaptive_interruptions on, the default for every agent, the agent uses Mirai’s turn-taking:
  • It knows when the caller has finished speaking, and answers then.
  • When the caller pauses in the middle of a thought, it waits and says a short “hmm” so they know it is still listening.
  • When the caller asks for a moment (“give me a minute”), it holds until they come back.
  • While it speaks, it ignores voices much quieter than the caller’s, such as someone else in the room. Those voices do not stop it, and their words are not passed to the agent.
  • If an interruption turns out to be nothing, it picks up the line it was cut off on.
Mirai’s turn-taking is available when the agent uses Mirai’s own LLM. An agent on another LLM provider follows the fixed rules, even with adaptive_interruptions on.

Fixed rules

Set adaptive_interruptions to false and the agent follows fixed rules. The interruptions preset sets how much the caller has to say to stop it, and pass-through words never stop it. A clear stop word such as “stop” or “ruko” interrupts at every setting except never. The preset and the pass-through words still apply while adaptive_interruptions is on. The console shows them only when the switch is off, and switching it on there sets interruptions back to normal. On a node-based agent, a node with allow_interrupt: false is never interrupted whatever this setting is, and never applies to every node.

Pass-through words

Callers often say a short word while the agent talks, to show they are listening. The built-in acknowledgements, “haan”, “ji”, “ok”, “hmm” and their equivalents, never interrupt at any setting. Add the words your own callers use with pass_through:
A reply made only of acknowledgements and pass-through words, in any mix, does not stop the agent. Case and punctuation do not matter. With the list above, “Haan, theek hai.” passes through. “Theek hai, ek sawaal hai” is treated like any other speech, because “ek sawaal” is not on the list. The API saves each entry like this:
  • An entry is literal text, never a pattern.
  • Unicode is normalised (NFC), spaces at either end are trimmed, and runs of spaces inside collapse to one.
  • After that, each entry is 1 to 40 characters and at most 4 words.
  • Duplicates are removed ignoring case. The first spelling and the order are kept.
  • At most 30 entries remain.
  • null is saved as [].
For example, [" Theek ", "theek", "bilkul"] is saved as ["Theek", "bilkul"]. A list outside these limits is refused with 400 invalid_request, and the message names the field: A pass_through that is not an array, or an entry that is not a string, gets the JSON decoder’s message instead. A Realtime session started from the agent does not use pass_through yet.

Change behavior with PATCH

PATCH merges behavior field by field: the fields you send change and the others keep their values, unlike other nested objects, which are replaced whole. pass_through is a list, so the list you send replaces the saved one. To add a word, read the agent, add the word to behavior.pass_through and send the whole list. Send [] or null to clear the list, or "behavior": null to go back to the defaults. The change takes effect on the next call and is saved with each agent revision. This request moves an agent to the fixed rules, with a firmer preset and three words of its own:
200 OK (excerpt)
To go back to turn-taking with the default preset, send { "behavior": { "adaptive_interruptions": true, "interruptions": "normal" } }. The pass-through words stay.
If your callers use a laptop’s built-in microphone in a busy room, keep adaptive_interruptions on and let the browser reduce noise. See Microphone capture.

Create an agent

Responds with 201 Created and the full agent object.

Get an agent

Responds with 200 OK and the agent object. You get 404 not_found if the agent was deleted, if the ID does not exist, or if it exists in another workspace. All three cases return the same response, so a 404 never hints that the ID is real. None of these cases returns 403; that status only means your key has been revoked. See errors.

List agents

200 OK
Each element is the full agent object, in the same shape GET /v2/agents/{id} returns, prompts included. There is no trimmed summary form, so a page of agents with long prompts makes a large response. Page through with limit instead of pulling everything at once. Deleted agents are excluded. See pagination.

Update an agent

Send only the fields you are changing. Nested objects such as voice, end_call, voicemail, background_sound, analysis and tools are replaced wholesale, so to change end_call.message, send the whole end_call object. behavior is the one exception: it is merged field by field, though a pass_through list you send replaces the saved list. See Change behavior with PATCH. flow is replaced wholesale too: send the whole graph, or use PUT /v2/agents/{id}/flow. "flow": null turns a node-based agent back into a single-prompt agent.
Responds with 200 OK and the updated agent object.
An update takes effect on the next call. Calls already queued, dialing or in_progress keep the configuration they were created with.

Delete an agent

204 No Content. The delete is soft: the agent stops appearing in GET /v2/agents and can no longer be used for new calls, but historical calls keep resolving their agent_id. Calls already in flight are not affected.

Read an agent’s logs

Everything that happened on this agent’s calls, newest first. One row per event: a tool run, a tool the model asked for that the agent doesn’t have, the variables a call received, the post-call analysis, and each call starting and ending. It’s the same list the console shows in Agent Studio under Logs, so you can debug from code or from the console and see the same rows.
200 OK
Page with next_cursor until has_more is false. See pagination. A variables row’s detail holds the values the call received, such as a customer’s name or order number. Treat logs like the call data they come from, and keep your API key on your server.
Rows about variables and results start from calls made on 14 October 2026. Rows about tools the model asked for but the agent doesn’t have start from 15 October 2026.

Count errors and warnings

How many errors and warnings each part had. Without since it counts the last 24 hours. These are the counts on Agent Studio’s section labels.
200 OK
Every part is always present, even when both counts are zero.

Writing a good prompt

A single-prompt agent does one job, start to finish, usually in under two or three minutes. The prompting guide covers this in detail. In short:
  • Name the job in the first line. “Confirm order {{order_id}}. Nothing else.”
  • Cap reply length explicitly. “One or two short sentences.” Long turns are the single biggest driver of perceived latency.
  • State the ending condition. “When the customer confirms or refuses, thank them and call end_call.” Without this the model keeps talking.
  • Put per-call data in variables, not the prompt. One agent can then run thousands of calls without being re-created.
  • Write in the language you will speak. A Hindi call driven by an English prompt code-switches badly. Write the Hindi lines in Devanagari.
Prompts that cause trouble: multi-branch scripts (“if they say X, then go through the following seven questions”), which belong in a node-based agent; instructions that assume the model remembers a previous call; and data the agent must fetch mid-call, which is a job for an on-call tool.