Skip to main content
v1 still runs for the integrations already on it, hosted separately at api.voice-agents.miraiminds.co. New features ship on v2 only, and we are moving v1 integrations to v2 one at a time. Your Mirai contact agrees the switch-over date with you. What you get on v2:
  • GET on a call. In v1, webhooks are the only way to learn a call’s status.
  • Campaigns, a server-side dialler with calling windows, retries, budgets, do-not-call suppression and a per-contact report. An always-on campaign is the v1 call queue.
  • Call analysis on the call, on its own endpoint and in a webhook, including the follow-up message template.
  • Your wallet balance over the API and on every call-ending webhook.
  • Idempotent call creation and a published rate card.
  • Tools before, during and after a call. Recreate each tool definition on your v2 agent; v1 tool IDs do not transfer.
Keep your v1 integration running until each part has its v2 replacement tested.

Hosts

The v1 host has /v2/ paths on itv1’s call endpoints really are named POST /v2/call/initiate. That /v2/ is a path segment inside the v1 product and has nothing to do with this API. Check the host to tell the two apart.

Authentication

v2 takes one header. The key carries the workspace, so valid credentials cannot reach the wrong workspace by accident. Create a key, and get the workspace’s webhook secret, in the console under Developers. See Start building.
The v2 API also accepts a v1 key pair, sent as the same x-public-key and x-private-key headers, once we have linked that pair to your v2 workspace. Ask your Mirai contact before you rely on it. The workspace header picks one of your sub-workspaces. A value that names neither a sub-workspace nor your own workspace is refused with 404 workspace_not_found, so leave the header out if you don’t run brands as sub-workspaces. A linked pair is a bridge for the move: v2 keys are the ones you can create, rotate and revoke in the console, so switch to one when you can.

Endpoints

Fields

Creating an agent / assistant

Set analysis.enabled: true to run the analysis at all. It is set per agent and reads every call of that agent that connected.

Placing a call

v1 → v2 call request
v1 → v2 response

Retries, calling hours and concurrency

In v1, every call you placed joined a queue on the assistant, which applied its calling slots, its concurrency limit and its retry protocol. POST /v2/calls places one attempt now: no calling window, no redial. To keep v1’s behaviour, create one campaign for the agent with "always_on": true, start it, and add each number to it with POST /v2/campaigns/{id}/contacts where you used to call POST /v2/call/initiate. The campaign calls each number inside its window, within its concurrency, and retries the ones that did not connect. It stays open after the list is done. See always-on campaigns for a worked example. Two differences to plan for. A campaign holds each phone number once, so adding a number already in it is counted as a duplicate and not called again. And an add to a campaign that has been stopped, or whose end_date has passed, gets 409 conflict. Any 200 means the numbers are in line to be called.

Statuses

v1’s status vocabulary is hyphenated and mixes phases with outcomes. v2 uses snake_case and separates status from ended_reason.

Webhooks

Point a new route at the v2 scheme. The two signatures are not interchangeable, and you need both routes while calls run on both versions. Signature verification has the code and a test vector.

Events

Exactly one terminal event fires per call: call.completed, call.voicemail, call.failed or call.aborted. Campaigns add campaign.* events. See event types.

Fields

v1 → v2 webhook body
Money is in rupees on v2, not credits: cost.amount_inr is what this call cost and wallet.balance_inr is what is left after it. The balance is a snapshot taken when the call was billed, and it is left out when we could not read it. The analysis moves from end-of-call to call.processed, which follows the terminal event once the analysis and any post-call tools have finished. Turn on final_results to get the transcript in the same event.

Message templates after the call

If your v1 assistant chose a message template after each call (analysisPlan.templatePlan, with the result at analysis.insights.template), use analysis.templates on the v2 agent. v1 sent {"assistantId": "<id>"} to your URL and read the Data list from the answer. A fetch can send exactly the same request, so your template endpoint keeps working unchanged:
v1 called your endpoint without credentials. On v2 you can add a header with a workspace secret, such as "headers": { "Authorization": "Bearer {{ secrets.templates_key }}" }, and check it on your side. Before you send a template, check that missing is empty, or fill those slots yourself.

Errors

v1’s success responses wrap the payload in { status_code, message, data }. v2 returns the resource itself. See the error reference.

A migration plan

  1. Get a v2 key and the webhook secret from Developers in the console. Keep your v1 credentials, because you will run both for a while.
  2. Recreate your assistants as agents. Move the opening line out of systemPrompt into first_message, rename your payload keys to flat variables keys your prompt references, and move analysisPlan to analysis, templates included.
  3. Point a new webhook route at the v2 signature scheme and the v2 event names. Do not modify the v1 route.
  4. Decide how calls are placed. For calls that need calling hours and retries, create an always-on campaign per agent and add numbers to it. For a call that must ring now, use POST /v2/calls with an Idempotency-Key.
  5. Switch one low-volume flow to v2 and compare its outcomes with the same flow on v1 for a day.
  6. Recreate and test your tools on the v2 agent, then move the remaining calls. Add your documents and website to a knowledge base and attach it to the v2 agent before moving assistants that use the v1 knowledge base.