Rate limits
Limits are per secret key.Request rate
Exceeding the request rate returns429 with error.code: rate_limited and
a Retry-After header in seconds. It is about how fast you call the API, not
about how many phones are ringing.
429 Too Many Requests
Concurrency
Call concurrency does not produce a429. A POST /v2/calls beyond
your concurrent-call ceiling is still accepted with 202 and sits in queued
until a slot frees, then dials — nothing is rejected and nothing is lost. On the
call path, 429 is request-rate only. (Text to speech is the
one exception: it has no queue, so it refuses.)
That makes the ceiling a pacer, not a gate. Two consequences:
- A queued call’s phone rings later than you asked. If a call is only useful
inside a window, check
statusbefore 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, furtherPOST /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
rate_limited code on purpose: the correct client
behaviour is identical — honour Retry-After and retry. Read error.message if
you want to log which one you hit.
The count is calls accepted and not yet ended — queued plus the handful
actually dialing or in_progress — not strictly queued. With a concurrency
of 5 the difference is at most 5 calls.
Queue depth is provisioned per workspace, like concurrency. If a campaign
genuinely needs to submit more than 500 rows in one batch, ask your Mirai contact before the
campaign, not during it.
Keeping the queue short is still the better shape, because a queue you own is
one you can reorder, cancel and re-prioritise. The simplest correct pattern:
sleep(). Answer rates vary by hour, and a
fixed delay either wastes capacity or hammers the limit.
Text to speech
The speech API has no queue, so its concurrency is a gate, not a pacer.at_capacity can also come from a deployment-wide ceiling when the speech node
is saturated — the same code, handled the same way. A refused request holds no
slot and is never charged.
Payload and duration ceilings
Campaign ceilings
Campaigns carry their own bounds, all enforced at the API edge with400 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 are a latency problem before they are a limit problem. The
transactional tier is tuned for prompts in the hundreds of tokens, not
thousands.
Timeouts
Data retention
Recordings and transcripts are available through the API —
GET /v2/calls/{id}/recording and
/transcript. Pull anything you need to keep
beyond 90 days into your own system, and tell us up front if your use case
requires that we not record at all.
India calling rules
You are the sender. Under Indian telecom regulation the obligations for commercial voice calls sit with the business placing them, not with the platform carrying them. Reading this page is not legal advice, and it is not a substitute for your own compliance review.Calling window
Commercial and promotional voice calls are restricted to daytime hours. The window applied in practice is 09:00–21:00 IST, and several enterprise programmes tighten it further to 10:00–19:00. On a campaign, the platform enforces the window you declare.timezone, start_date/end_date and 1–4 slots are evaluated in local time
on every dialling tick: outside the window the campaign sleeps in play and
rings nobody. Declaring 10:00–19:00 Asia/Kolkata is enough — you do not need
your own scheduler in front of it.
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. Gate those in your scheduler:
Consent and DNC/DND
- Get consent before you call. Explicit, recorded, and revocable. Keep the record — it is what you produce when a complaint arrives.
- Push your opt-outs to
POST /v2/dnc. That list is enforced by us: every campaign checks it at dial time, so a number added mid-campaign is suppressed from that moment, markedsuppressedin the report, and never billed. It does not apply to singlePOST /v2/calls— those are explicit. - 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.
- Transactional vs promotional matters. A delivery confirmation to an existing customer is treated differently from a marketing pitch to a cold list. Classify each campaign, and do not let a transactional pretext carry a promotional payload.
- 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. Put it in the agent’sfirst_message or its opening turn:
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.What we do enforce
Persistent complaint patterns against a workspace will get its keys suspended.
That is not a regulatory mechanism, it is ours — we would rather suspend one
campaign than lose the numbering range for everyone on the platform.