Skip to main content
Two kinds of limit apply to you: our technical limits, which we enforce, and India’s regulatory rules, which you are responsible for.

Rate limits

Limits are per secret key.
Pilot keys are provisioned individuallyThe numbers above are the defaults a new pilot key is issued with, and yours may differ. Confirm your actual ceilings with your account contact before you size a campaign. Higher concurrency only needs a provisioning change, so ask for it.

Request rate

Exceeding the request rate returns 429 with error.code: rate_limited and a Retry-After header in seconds. This limit measures how fast you call the API, not how many phones are ringing.
429 Too Many Requests

Concurrency

Call concurrency does not produce a 429. A POST /v2/calls beyond your concurrent-call ceiling is still accepted with 202. It waits in queued until a slot frees and then dials, so no call is rejected or lost. On the call path, 429 is request-rate only. (Text to speech over HTTP is the one exception: it has no queue, so it refuses the request.) So the ceiling paces your calls instead of refusing them. That has two consequences:
  • A queued call’s phone rings later than you asked. If a call is only useful inside a window, check status before you assume it went out, or do not submit it until you have the capacity.
  • Submitting a burst does not fail; it builds a queue that drains at your concurrency.

Queue depth

The queue itself is bounded. Once you have 500 calls accepted and not yet ended, further POST /v2/calls return 429 rate_limited with a Retry-After header until calls drain. The message names the ceiling, so you can tell it apart from a request-rate 429:
429 Too Many Requests
Both limits share the rate_limited code on purpose, because your client should handle them the same way: honour Retry-After and retry. Read error.message if you want to log which one you hit. The count covers calls accepted and not yet ended. That is queued plus the few calls actually dialing or in_progress, not queued alone. With a concurrency of 5, the difference is at most 5 calls. Queue depth is provisioned per workspace, like concurrency. If a campaign needs to submit more than 500 rows in one batch, ask your Mirai contact before the campaign starts, not during it. Even so, it is better to keep our queue short and hold the rest on your side, where you can reorder, cancel and re-prioritise it. The simplest correct pattern looks like this:
Do not drive pacing off a fixed sleep(). Answer rates vary by hour, and a fixed delay either wastes capacity or hammers the limit.

Text to speech

Every workspace has one pool of synthesis slots, 10 by default. An HTTP request to the speech API holds a slot while it runs, and so does each sentence on a WebSocket stream while it is being synthesised. An open socket that is not speaking holds none. The two handle a full pool differently. The HTTP endpoint has no queue, so it refuses the request. On a stream, a sentence whose turn has come waits up to 3 seconds for a slot, in a queue shared by all your sockets, before it fails. at_capacity can also come from a deployment-wide ceiling when the speech node is saturated. It is the same code, and you handle it the same way. A refused request holds no slot and is never charged. The limit is raised on request, with no change to your code. If you run many calls at once, ask your Mirai contact for a limit a little above your peak number of simultaneous calls: each speaking call needs a slot most of the time, and it starts its next sentence shortly before the current one ends. Streams have their own limits: See Streaming text to speech for what each limit does to an open socket.

Speech to text

A workspace can run 10 speech-to-text sessions at once. Each HTTP request is a session while it runs, and so is each open socket. One more returns 429 at_capacity with Retry-After and costs nothing; a socket is refused before the upgrade. The limit is raised on request, with no change to your code. See the STT quickstart and the WebSocket reference for what each limit does.

Payload and duration ceilings

Invalid values return 400 invalid_request.

Call timing

max below is the call’s effective max_duration_secs. See timing policy.

Live events

These apply to every call’s live event stream: phone, campaign, inbound, browser and realtime.

Browser calls

Node-based agents

We check a node-based agent’s flow on every save. A flow over a graph limit returns 400 invalid_flow with the path of each problem. A generation or transcription request over its limits returns 400 invalid_request. A flow generation typically takes 15 to 60 seconds, depending on the model; set a client timeout of a few minutes. When the generator is busy with other requests, it answers 429 rate_limited with Retry-After, and that refusal does not count against the hourly limit. A transcription typically takes 5 to 10 seconds for a two-minute call, and the transcriber answers 429 the same way when it is busy. Each generation and transcription is charged to your wallet at the provider’s reported cost plus 20%; see AI flow drafts.

Offline transcription

Offline transcription checks the job count and your wallet before it reads the recording, and nothing is charged for a refused request.

Campaign ceilings

Campaigns carry their own bounds, all enforced at the API edge with 400 invalid_request. Bad contact rows do not fail the batch: they come back by index in contacts_rejected. Only exceeding 1000 rows fails the whole request. Long prompts add latency well before they reach a size limit. The stack is tuned for prompts in the hundreds of tokens, not thousands.

Timeouts

Data retention

You can fetch recordings and transcripts through the API with GET /v2/calls/{id}/recording and /transcript. Pull anything you need to keep beyond 90 days into your own system. To store no audio, create calls with recording_enabled: false, or ask us to turn recording off for your whole workspace. Save your own copy of each offline transcript when its job completes. If a transcript is no longer available, its job still reads completed with its cost, but without the text. To have a transcript removed, write to help@miraiminds.co.

India calling rules

Under Indian telecom regulation you are the sender: the obligations for commercial voice calls sit with the business placing them, not with the platform carrying them. This page is not legal advice, and it does not replace your own compliance review.

Calling window

Commercial and promotional voice calls are restricted to daytime hours. The window applied in practice is 09:00 to 21:00 IST, and several enterprise programmes tighten it further to 10:00 to 19:00. On a campaign, the platform enforces the window you declare. The platform evaluates timezone, start_date/end_date and 1 to 4 slots in local time on every dialling tick. Outside the window the campaign stays in play but rings nobody. Declaring 10:00 to 19:00 Asia/Kolkata is enough, and you do not need your own scheduler in front of it.
On a single POST /v2/calls there is no window. A direct call is an explicit instruction to ring one number now, and it will dial at 02:00 IST if you ask it to. Enforce the window for those calls in your own scheduler:
  • Get consent before you call. Consent should be explicit, recorded and revocable. Keep the record, because you will need to produce it when a complaint arrives.
  • Push your opt-outs to POST /v2/dnc. We enforce that list: every campaign checks it at dial time, so a number added mid-campaign is suppressed from that moment, marked suppressed in the report, and never billed. It does not apply to single POST /v2/calls, because a single call is an explicit instruction.
  • Scrub against the DND registry (TRAI’s Do Not Disturb / NCPR list) as well. We do not scrub against the national register for you, and our suppression list is not a substitute for it. A number can register between two campaigns.
  • Honour opt-outs immediately. If a customer says “stop calling me” during a call, that is an opt-out. Capture it and suppress the number on every channel it applies to.
  • Classify each campaign as transactional or promotional. A delivery confirmation to an existing customer is treated differently from a marketing pitch to a cold list. Do not put promotional content in a call you present as transactional.
  • Register as required. Commercial communication under TCCCPR 2018 runs through registered entities, headers and consent templates. Confirm your registration status with your telecom provider or counsel.

Disclosure that it is an AI

Tell people they are talking to an AI. Put the disclosure in the agent’s first_message or its opening turn:
Regulation worldwide is moving in this direction, and the disclosure costs you one clause. In practice it also reduces early hang-ups, because callers who feel misled are more likely to hang up than callers who were told.

Recording

If you record calls, say so in the opening turn and keep the recordings under the same retention and access controls as the rest of your customer data. If you do not need the audio, do not store it: recording_enabled: false keeps no recording for that call, and a workspace with recording turned off refuses recording_enabled: true with 403 recording_disabled.

What we do enforce

If complaints against a workspace persist, we suspend its keys. This is our own policy rather than a regulatory one: we would rather suspend one campaign than lose the numbering range for everyone on the platform.