Skip to content

Plans & limits

The four plans and what each includes, which limits actually block a create, the 120-per-minute API rate limit, call concurrency, and every field and size bound in one table.

Open Billing

There are two kinds of limit here and confusing them wastes an afternoon. Plan limits govern how many things your workspace can own — agents, knowledge bases, deployments, team seats. API limits govern individual requests — how fast you may call, how long a field may be, how many items a page may hold.

Plan limits are enforced in the console and in the platform when you create a resource, and your plan's monthly allowances decide when new conversations and calls need credits. API limits are enforced on every request. Your plan does not change your rate limit.

Plans #

Four plans. Prices are per month and exclude GST.

Free Starter Growth Enterprise
Plan id free starter growth enterprise
Price / month ₹0 · $0 ₹2,999 · $39 ₹7,999 · $99 Custom
AI agents 1 3 10 Custom (up to 20)
Knowledge bases 1 3 10 Custom (up to 50)
Deployments 3 9 40 Custom
Team seats 2 3 10 Custom
AI conversations / month 100 1,000 5,000 Custom
Voice minutes / month — Pay-as-you-go at ₹6 · $0.07 per min 500 included, then ₹6 · $0.07 per min Custom
Phone numbers — ₹399 · $3.99 per number/month 1 included, then ₹399 · $3.99/month Custom
Usage beyond the allowance Refused until the 1st Paid from credits Paid from credits Per contract
Channels Web chat Web chat, WhatsApp, and voice paid from credits Everything, including voice Everything
Campaigns — — Yes, up to 5,000 recipients per launch Yes

Money is shown as INR · USD. Your workspace bills in one of the two, fixed when it was created — see your workspace currency. Prices exclude tax.

A conversation is one customer-to-agent thread on one channel, lasting up to 20 transactions (normally 10 exchanges) or 24 hours, whichever comes first. The same person messaging you on WhatsApp on Monday and again on Wednesday is two conversations. A long thread on Monday that passes 20 transactions rolls into a second one.

Plans are monthly. An unknown or unreadable plan id resolves to free.

You compare and change plans on Billing. Upgrades, downgrades & trials explains what each move does.

Locked features #

A feature your plan doesn't include shows a Plan chip beside it in the sidebar, and its page shows Upgrade to unlock. Campaigns, for example, are locked on Free and Starter. The owner gets a View plans & upgrade button; everyone else is asked to talk to the owner.

Voice is a separate meter from conversations

Voice minutes are counted on their own and are deliberately excluded from the conversation count, so a call is not billed twice. Web chat and WhatsApp conversations share one allowance. Conversations and voice minutes reset on the 1st of each UTC calendar month, whatever day your subscription renews on.

What is actually enforced #

This distinction matters more than the table above, because it tells you which limits can fail a request.

Three limits block a create. When you are at the cap, the create is refused with the message below and nothing is written:

Limit Enforced when Message
knowledge_bases You create a knowledge base Your plan includes {limit} knowledge base(s). Upgrade to add more.
deployments You create a deployment Your plan includes {limit} deployment(s). Upgrade to add more.
members You invite a team member Your {Plan} plan includes {limit} team seats and they're all used (including pending invites). Upgrade your plan to add more.

Agents are not refused at the plan cap when you create one in the console. The console stops only at the 20-agent ceiling, with Agent limit reached for this organization. Don't rely on the console to hold you to your plan's agent count: keep to the number in the table above. Archive an agent you no longer use rather than creating past it.

Seats count active members plus pending invites. An invitation that nobody has accepted still occupies a seat, which is the usual explanation for a workspace that appears to have room and does not. Cancel stale invites before you buy more seats.

Conversations and voice minutes are monthly meters. They are counted and shown on Billing. They never block a create. What happens when one runs out depends on the plan:

  • Starter and Growth: usage past the allowance is paid from credits, at ₹6 · $0.07 per voice minute and ₹2 · $0.02 per conversation. If the credit balance is also at zero, new conversations and calls on that meter are refused, inbound as well as outbound, until you top up. See What happens when you run out.
  • Free: the allowance is a hard cap. After 100 conversations, new web chat and WhatsApp conversations are refused until the 1st.

A conversation or call already in progress is never cut off.

An unpaid plan invoice is different from a spent meter. Once the workspace is suspended, everything that serves customers stops, including web chat conversations that are already open: no agent replies on web chat or WhatsApp, no WhatsApp message or call goes out, campaigns are held, and API keys are refused. Credits don't lift it; paying the invoice does. See When a payment fails.

Downgrading keeps what you've built, but not everything

If you drop from Growth to Starter with six knowledge bases, all six keep working. You just can't create another until you're back under the cap. The same goes for deployments and seats. Moving to Free is different: your WhatsApp number and phone numbers stop answering, and after 7 days the phone numbers are released for good. See Moving to Free.

Two more properties worth knowing:

  • Enforcement fails open. If the entitlement lookup cannot be read, the create is allowed. A blip in our infrastructure will never block you from adding an agent. It also means an occasional create can slip past a cap; the next one will not.
  • There are absolute backstops above the plan caps. A workspace cannot exceed 20 agents or 50 knowledge bases regardless of plan. You will meet your plan limit long before either.

On /api/v1, the same allowances apply. POST /messages is refused with allowance_exhausted and POST /calls with wallet_empty when the meter and the credits are both spent. A call on a number the plan no longer includes is refused with channel_dormant. Errors lists every reason.

Campaign recipients #

A campaign has two ceilings.

Ceiling Value Behaviour
Absolute 50,000 recipients per campaign Never moves, on any plan
Plan campaign_recipients on your plan Checked at launch

Both are checked before anything is sent, and both block the launch rather than truncating the list. Sending to the first thousand of a five-thousand-person audience and silently dropping the rest would be worse than refusing: you would believe the campaign ran.

The refusal names your limit and your audience size, with details.reason of plan_limit or audience_too_large.

This counts eligible recipients, not rows

The check runs after opt-outs, duplicates and unusable numbers are removed — so a 52,000-row file with 3,000 opt-outs passes. The console shows both numbers.

Like every other plan check, this one fails open: if entitlements cannot be read, the launch is allowed and the absolute ceiling still applies.

Two limits on campaigns are not plan-based and cannot be raised by upgrading:

  • 300 outbound calls per workspace per day. A call campaign launched after the day's 300 are used is refused; one bigger than what's left today launches with a warning that only part of it will be called today. Split large call lists across days.
  • 4 campaign messages to one person per rolling week. See Frequency caps.

API rate limit #

Text
120 requests per key, per minute

Counted in a fixed one-minute window keyed on the wall clock, not a sliding window. At the top of each minute the counter resets to zero. The counter is shared across every server that handles your traffic, so the limit is global rather than per-instance.

The limit is per key, not per workspace. Three keys give you three independent budgets, which is the cheapest way to stop a backfill starving your production sends.

Headers #

On every successful response where a key was checked:

Text
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87

Read X-RateLimit-Remaining and slow down before you are rejected. Note the asymmetry: these headers appear on success only. A 4xx or 5xx — including the 429 itself — carries no X-RateLimit-* header.

When you exceed it #

429 Too Many Requests
{
"error": {
"code": "rate_limited",
"message": "Rate limit of 120 requests/minute exceeded for this key.",
"details": { "reason": "rate_limited", "limit": 120, "window_seconds": 60 },
"request_id": "req_01JQRS4T8XZ0AB1CD2EF3GH4",
"correlation_id": "cor_01JQRS4T8XZ0AB1CD2EF3GH4"
}
}

There is no Retry-After header and no X-RateLimit-Reset header. Because the window is a wall-clock minute, sleeping until the next minute boundary is the correct backoff and anything shorter is a wasted request:

Python
import time
time.sleep(60 - (time.time() % 60) + 0.25)

If the counter store is unreachable, the limiter fails open and your request is served. You will never be rejected because our rate limiter had a bad day.

For bulk work, pace at roughly two requests per second rather than bursting and absorbing rejections. Rate limits covers pacing patterns in more depth.

Concurrent outbound calls #

Text
10 live calls per workspace

Separate from the request limit, counted differently, and reported differently. This one counts calls that are currently ringing or in progress across the whole workspace, regardless of which key placed them.

429 Too Many Requests
{
"error": {
"code": "rate_limited",
"message": "This workspace already has 10 calls in progress (limit 10). Try again shortly.",
"details": { "reason": "call_concurrency", "limit": 10 },
"request_id": "req_01JQRS4T8XZ0AB1CD2EF3GH4",
"correlation_id": "cor_01JQRS4T8XZ0AB1CD2EF3GH4"
}
}

Both limits produce 429 with code: "rate_limited", so branch on details.reason to tell them apart. rate_limited means slow down; call_concurrency means wait for a call to end. A loop that fires 200 calls will meet this on the eleventh — queue them and drain the queue as call.ended events arrive.

Field and size limits #

Every one of these is enforced at validation. Exceeding one returns 400 with code: "invalid_argument", the message Request validation failed., and details.errors naming the field.

Field Endpoint Limit
text POST /messages 4096 characters
to POST /messages, POST /calls 6–20 characters, pattern ^\+?\d+$
sender_id POST /messages 64 characters
template.name POST /messages 1–120 characters
template.language POST /messages 16 characters
agent_id POST /calls 64 characters
from_number POST /calls 20 characters
purpose POST /calls 500 characters
ring_seconds POST /calls 10–90, default 30
subject POST /tickets 1–240 characters
description POST /tickets 1–8000 characters
priority POST /tickets One of low, normal, high, urgent — default normal
tags POST /tickets At most 10 items
name POST /contacts 120 characters
email POST /contacts 200 characters
phone POST /contacts 32 characters
Idempotency-Key Header Truncated to 200 characters

Non-request limits that show up in the same conversations:

Thing Limit
Maximum call length 60–3600 seconds, default 600
Web chat image upload 5 MB, on paid plans only
Knowledge base file upload 15 MB per file

Phone number formatting is stricter than it looks

^\+?\d+$ means digits with an optional leading + and nothing else. +919876543210 and 919876543210 both pass. +91 98765 43210, +91-98765-43210, and (+91) 98765 43210 are all rejected at validation. Normalise before you send. Responses always come back as + followed by digits.

There is no media or attachment upload on POST /messages — text and approved templates only. There is no batch send endpoint and no scheduling parameter.

Pagination bounds #

Endpoint limit range Default
GET /conversations 1–100 25
GET /conversations/{id}/messages 1–200 100
GET /agents No limit parameter Returns everything

A limit outside its range is a 400, not a silent clamp. GET /agents returns the same {items, next_cursor} envelope as the others but never paginates — next_cursor is always null.

next_cursor is non-null only when a page came back full. A short page ends the walk. See Pagination.

Retention #

Thing Kept for
API request log 7 days
Webhook delivery records 7 days
Idempotency records 24 hours
Key roll grace window 24 hours
WhatsApp session window 24 hours
Webhook signature timestamp tolerance 5 minutes

The request log is the one you will use. The /api/v1 calls your keys made appear under Developers → Logs with time, method and path, key name, status with error code, and duration, for seven days. Request ids and correlation ids are not shown. Requests refused before the key is accepted (a 401, a suspended workspace's 403, or a rate-limit 429) do not appear.

If you need call or conversation history beyond what the console shows, pull it into your own store — Sync conversations into your warehouse is the job for that.

Rate limits in depth

The window, the headers, and pacing — including what a backfill costs.

Going live

The pre-launch checklist — including how to work out your rate-limit headroom.

Troubleshooting

Symptom-first index — including both flavours of 429.

Errors

Every code and reason in one place.