Assistants
An assistant is v1’s agent: prompt, voice identity, telephony bindings, call
settings, knowledge base and post-call analysis plan. All endpoints are
workspace-scoped — send the workspace header.
Variants
Section titled “Variants”variant.type | Use for |
|---|---|
custom | Recommended for everything you author. You write agent.systemPrompt and declare variables in variant.config.inputSchema. |
abandoned_cart | A built-in Shopify cart-recovery flow. Configure variant.config.abandoned_cart. |
Create an assistant
Section titled “Create an assistant”POST /v1/admin/assistant/createCore fields
Section titled “Core fields”| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Max 40 characters. Unique per workspace. |
variant.type | enum | yes | custom | abandoned_cart |
variant.config.inputSchema | array | no | Variables the prompt references. See variables. |
agent.identity | object | yes | { name, gender, voice } — gender is male or female, voice is a slug from the voice gallery. |
agent.systemPrompt | string | no | The instructions. Supports {{placeholders}}. |
agent.firstMessage | string | no | Spoken on connect. If empty, a greeting is generated from the identity and ICP language. |
agent.endMessage | string | no | Spoken just before hanging up. |
agent.tools | string[] | no | API tool _id values the assistant may call. |
telephony.inbound / .outbound | string | no | Telephony number _ids. |
icpContext | object | no | See ICP context. |
callSettings | object | no | See call settings. |
analysisPlan | object | no | See analysis plan. |
knowledgeBase | object | no | See Knowledge Base. |
preCall | object | no | See pre-call enrichment. |
curl -X POST https://api.voice-agents.miraiminds.co/v1/admin/assistant/create \
-H "x-public-key: pk_1234567890abcdef1234567890abcdef" \
-H "x-private-key: sk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "workspace: 6690a1b2c3d4e5f600000002" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Update Assistant",
"variant": {
"type": "custom",
"config": {
"inputSchema": [
{ "name": "customerName", "type": "string", "isRequired": true },
{ "name": "orderId", "type": "string", "isRequired": true },
{ "name": "deliveryDate", "type": "string", "isRequired": false }
]
}
},
"agent": {
"identity": { "name": "priya", "gender": "female", "voice": "priya" },
"systemPrompt": "You are Priya from Acme. Greet {{customerName}} and confirm order {{orderId}}. If a delivery date is available, mention it: expected {{deliveryDate}}.",
"firstMessage": "Hi {{customerName}}, this is Priya from Acme.",
"endMessage": "Thank you for your time. Have a great day!"
},
"icpContext": { "language": "hinglish" },
"callSettings": {
"slots": [{ "startTime": "09:00", "endTime": "21:00" }],
"maxCallDuration": 200,
"concurrentCallCount": 5,
"retryProtocol": {
"maxAttemptsNoPickup": 2,
"maxAttemptsLowEngagement": 1,
"reAttemptPeriod": 300,
"maxRescheduleCount": 1
}
}
}'import os, httpx
API = "https://api.voice-agents.miraiminds.co"
H = {
"x-public-key": os.environ["MIRAI_PUBLIC_KEY"],
"x-private-key": os.environ["MIRAI_PRIVATE_KEY"],
"workspace": os.environ["MIRAI_WORKSPACE"],
}
assistant = httpx.post(
f"{API}/v1/admin/assistant/create",
headers=H,
json={
"name": "Order Update Assistant",
"variant": {
"type": "custom",
"config": {
"inputSchema": [
{"name": "customerName", "type": "string", "isRequired": True},
{"name": "orderId", "type": "string", "isRequired": True},
]
},
},
"agent": {
"identity": {"name": "priya", "gender": "female", "voice": "priya"},
"systemPrompt": "You are Priya from Acme. Greet {{customerName}} and confirm order {{orderId}}.",
"firstMessage": "Hi {{customerName}}, this is Priya from Acme.",
},
"icpContext": {"language": "hinglish"},
"callSettings": {
"slots": [{"startTime": "09:00", "endTime": "21:00"}],
"maxCallDuration": 200,
"concurrentCallCount": 5,
"retryProtocol": {"maxAttemptsNoPickup": 2, "reAttemptPeriod": 300},
},
},
timeout=30,
).raise_for_status().json()
print(assistant["data"]["_id"])const API = "https://api.voice-agents.miraiminds.co";
const H = {
"x-public-key": process.env.MIRAI_PUBLIC_KEY,
"x-private-key": process.env.MIRAI_PRIVATE_KEY,
workspace: process.env.MIRAI_WORKSPACE,
"Content-Type": "application/json",
};
const res = await fetch(`${API}/v1/admin/assistant/create`, {
method: "POST",
headers: H,
body: JSON.stringify({
name: "Order Update Assistant",
variant: {
type: "custom",
config: {
inputSchema: [
{ name: "customerName", type: "string", isRequired: true },
{ name: "orderId", type: "string", isRequired: true },
],
},
},
agent: {
identity: { name: "priya", gender: "female", voice: "priya" },
systemPrompt:
"You are Priya from Acme. Greet {{customerName}} and confirm order {{orderId}}.",
firstMessage: "Hi {{customerName}}, this is Priya from Acme.",
},
icpContext: { language: "hinglish" },
callSettings: {
slots: [{ startTime: "09:00", endTime: "21:00" }],
maxCallDuration: 200,
concurrentCallCount: 5,
retryProtocol: { maxAttemptsNoPickup: 2, reAttemptPeriod: 300 },
},
}),
});
const { data } = await res.json();200 OK — the created assistant under data.
| Status | Cause |
|---|---|
400 | Validation error |
409 | An assistant with this name already exists in the workspace |
Variables
Section titled “Variables”Declare each variable in variant.config.inputSchema, reference it in
agent.systemPrompt / agent.firstMessage as {{name}}, and supply its value
per call. Nested values use dot paths: {{customer.firstName}}.
{
"inputSchema": [
{ "name": "customerName", "type": "string", "isRequired": true },
{ "name": "orderId", "type": "string", "isRequired": true }
]
}type is one of string, number, boolean, object, array; nested shapes
use fields. A placeholder with no matching value is left in the prompt
verbatim — the assistant will read the braces aloud. Always send every
required variable.
ICP context
Section titled “ICP context”Shapes tone, vocabulary and pace.
| Field | Values |
|---|---|
language | hinglish, english, hindi, telugu, tamil, kannada, malayalam, gujarati, punjabi, odia, marathi |
targetAgeGroups | gen_z, millennials, gen_x, boomers |
locationTiers | metro_urban, tier1, tier2, tier3, rural |
targetAudience | male, female, children |
Call settings
Section titled “Call settings”| Field | Type | Notes |
|---|---|---|
slots | array | Required. At least one { startTime, endTime } in HH:MM, in the workspace timezone. Calls run only inside these windows. |
maxCallDuration | number | Seconds. |
concurrentCallCount | number | Maximum 10. |
retryProtocol | object | See below. Required. |
{
"retryProtocol": {
"maxAttemptsNoPickup": 2,
"maxAttemptsLowEngagement": 1,
"reAttemptPeriod": 300,
"maxRescheduleCount": 1
}
}| Field | Default | Meaning |
|---|---|---|
maxAttemptsNoPickup | 2 | Rang, nobody answered — retry this many times. |
maxAttemptsLowEngagement | 1 | Answered but cut immediately — retry this many times. |
reAttemptPeriod | 300 | Seconds between attempts. |
maxRescheduleCount | 1 | Callbacks the customer can request. Maximum 5. |
slots is v1’s calling-window enforcement. Set it to your compliant window —
see India calling rules.
Analysis plan
Section titled “Analysis plan”Post-call AI evaluation. Results arrive on the end-of-call
event.
| Field | What it does |
|---|---|
successCriteriaPlan | A prompt that must return true or false. Write explicit, enumerated conditions. |
summaryPlan | A prompt producing a plain-English summary. Tell it what to cover. |
callInsightPlan | Structured fields extracted from the call. |
{
"analysisPlan": {
"successCriteriaPlan": "Return true ONLY if the customer explicitly confirmed the order AND agreed to the total price AND chose a payment method. Return false if they were 'just checking' or asked for more discount after the final price.",
"summaryPlan": "Summarize: (1) the customer issue, (2) the resolution, (3) sentiment, (4) follow-up needed."
}
}Vague success criteria produce vague booleans. Enumerate the conditions and state the false cases explicitly.
Pre-call enrichment
Section titled “Pre-call enrichment”If preCall.apiPlan.url is set, we call your endpoint before the call connects
(inbound or outbound) and merge the returned data into the call’s variables, so
your {{placeholders}} can use it — greeting an inbound caller by name, for
example.
We send number and assistantId as query parameters for method: get, or as
a JSON body for method: post. Keep the endpoint fast: it sits in front of the
call.
Get an assistant
Section titled “Get an assistant”GET /v1/admin/assistant/get/{assistantId}curl https://api.voice-agents.miraiminds.co/v1/admin/assistant/get/68c128a658cd7d0668bce78d \
-H "x-public-key: pk_1234567890abcdef1234567890abcdef" \
-H "x-private-key: sk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "workspace: 6690a1b2c3d4e5f600000002"200 with the assistant under data; 404 if it is not in this workspace.
List assistants
Section titled “List assistants”GET /v1/admin/assistant/listReturns every assistant in the workspace under data.
Update an assistant
Section titled “Update an assistant”PUT /v1/admin/assistant/update/{assistantId}Send the fields you want to change.
curl -X PUT https://api.voice-agents.miraiminds.co/v1/admin/assistant/update/68c128a658cd7d0668bce78d \
-H "x-public-key: pk_1234567890abcdef1234567890abcdef" \
-H "x-private-key: sk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "workspace: 6690a1b2c3d4e5f600000002" \
-H "Content-Type: application/json" \
-d '{ "callSettings": { "maxCallDuration": 180, "concurrentCallCount": 3 } }'| Status | Cause |
|---|---|
400 | The assistant is archived and cannot be updated |
404 | Not found |
409 | Another assistant already has that name |
There is no delete. Archive the workspace or organization instead.
Voice gallery
Section titled “Voice gallery”GET /v1/admin/voice-galleryThe catalogue of available voices. The slug is what goes in
agent.identity.voice — and in v2’s voice.voice_id.
curl https://api.voice-agents.miraiminds.co/v1/admin/voice-gallery \
-H "x-public-key: pk_1234567890abcdef1234567890abcdef" \
-H "x-private-key: sk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"{
"status_code": 200,
"message": "Voices fetched successfully.",
"data": [
{
"_id": "6690a1b2c3d4e5f600000301",
"slug": "priya",
"sampleAudio": "https://cdn.miraiminds.co/voices/priya.wav"
}
]
}Listen to sampleAudio before you pick. Voice choice moves answer-through rates
more than prompt wording does.