> ## Documentation Index
> Fetch the complete documentation index at: https://docs.miraiminds.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Assistants

> Create, read, list and update v1 assistants — prompts, identity, variants, call settings and analysis plans.

<Note>
  **This documents the v1 product.** It is kept for integrations already running
  on it. If you are building something new, start with the
  [Quickstart](/v2/quickstart).
</Note>

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

| `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

```http theme={null}
POST /v1/admin/assistant/create
```

### 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](#variables).                                                           |
| `agent.identity`                  | object    | yes      | `{ name, gender, voice }` — `gender` is `male` or `female`, `voice` is a slug from the [voice gallery](#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](/v1/tools) `_id` values the assistant may call.                                                              |
| `telephony.inbound` / `.outbound` | string    | no       | Telephony number `_id`s.                                                                                                |
| `icpContext`                      | object    | no       | See [ICP context](#icp-context).                                                                                        |
| `callSettings`                    | object    | no       | See [call settings](#call-settings).                                                                                    |
| `analysisPlan`                    | object    | no       | See [analysis plan](#analysis-plan).                                                                                    |
| `knowledgeBase`                   | object    | no       | See [Knowledge Base](/v1/knowledge-base).                                                                               |
| `preCall`                         | object    | no       | See [pre-call enrichment](#pre-call-enrichment).                                                                        |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    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
          }
        }
      }'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    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"])
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    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();
    ```
  </Tab>
</Tabs>

**`200 OK`** — the created assistant under `data`.

| Status | Cause                                                       |
| :----- | :---------------------------------------------------------- |
| `400`  | Validation error                                            |
| `409`  | An assistant with this name already exists in the workspace |

### 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}}`.

```json theme={null}
{
  "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.

<Warning>
  **Documented inconsistency**

  The API description text calls the per-call values object `variableValues`,
  while the `POST /v2/call/initiate` request schema and all of its examples use
  **`payload`**. `payload` is what the endpoint accepts. See
  [Calls](/v1/calls#initiate-a-call).
</Warning>

### 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

| 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.**                                                                                                        |

```json theme={null}
{
  "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](/v2/limits#india-calling-rules).

### Analysis plan

Post-call AI evaluation. Results arrive on the [`end-of-call`](/v1/webhooks#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.                                          |

```json theme={null}
{
  "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

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

```http theme={null}
GET /v1/admin/assistant/get/{assistantId}
```

```bash theme={null}
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

```http theme={null}
GET /v1/admin/assistant/list
```

Returns every assistant in the workspace under `data`.

## Update an assistant

```http theme={null}
PUT /v1/admin/assistant/update/{assistantId}
```

Send the fields you want to change.

```bash theme={null}
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](/v1/workspaces#archive) the workspace or
organization instead.

## Voice gallery

```http theme={null}
GET /v1/admin/voice-gallery
```

The catalogue of available voices. The `slug` is what goes in
`agent.identity.voice` — and in [v2's](/v2/agents#voice) `voice.voice_id`.

```bash theme={null}
curl https://api.voice-agents.miraiminds.co/v1/admin/voice-gallery \
  -H "x-public-key: pk_1234567890abcdef1234567890abcdef" \
  -H "x-private-key: sk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
```

```json title="200 OK" theme={null}
{
  "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.
