Billing & Pricing
How usage is metered, what each meter costs, and how to read a charge back to the call that caused it.
The API is the source of truth
GET /functions/v1/pricing, which is the same catalogue record_usage() charges against. The tables here are a snapshot for reading; if a number ever disagrees with the API, the API is right. Rates last reviewed 10 August 2026.How billing works
Converse is prepaid. You top up a wallet, and usage is drawn down against that balance as it happens. There is no monthly bill and nothing is invoiced in arrears — the only invoice you receive is a GST tax invoice covering usage you have already funded.
- Metered as it happens. The agent worker flushes usage every 30 seconds and once more at the end of the session, so a crashed worker loses at most half a minute.
- Idempotent. Every charge carries a key derived from the session and the tick number. A worker that retries after a network timeout bills once.
- Credit first, wallet second. Credit grants are drawn down oldest-expiring-first before the paid balance is touched.
- Tax held back. GST accrued on usage is subtracted from the spendable balance, so a call can never be funded with money already owed to the exchequer.
- In-flight calls finish. A session already running is allowed to take the balance negative; a new one is not started on empty.
Two ways to be charged
Pay per second
One voice.second_* meter covers the whole AI side of a session: transcription, synthesis, the language model, orchestration, tools and knowledge retrieval. Billed by the second with a ten-second minimum per session. Telephony and channels still meter separately.
| Meter key | Name | Unit | Rate | Free / mo |
|---|---|---|---|---|
voice.second_standard | Voice — Standard stack | second | ₹0.05 | — |
voice.second_premium | Voice — Premium stack | second | ₹0.08333 | — |
Per connected minute that works out to ₹3.00 (Standard) and ₹7.00 (Premium) for the AI, plus ₹1.00 for a carrier minute — so ₹4.00 and ₹6.00 all-in on the phone, and the AI figure alone for web and in-app sessions.
A third tier used to exist
voice.second_lite was retired on 10 August 2026. It cost ₹0.15 a minute less to run than Standard and was priced ₹1.20 below it, so it sold a discount rather than a different product. stack=lite still resolves to Standard on the quote endpoint, and agents configured for it are billed as Standard.Component pricing
Every part of the pipeline metered on its own unit. Model tokens are passed through at the provider's published list price with a small buffer for currency movement — Converse earns on the agent runtime and on its own models, not on reselling somebody else's.
Free allowances apply to the pay-as-you-go plan and reset monthly.
| Meter key | Name | Unit | Rate | Free / mo |
|---|---|---|---|---|
ai.orchestration_minute | Agent runtime | minute | ₹0.90 | 100 |
ai.stt_minute | Vernier STT | minute | ₹0.55 | 100 |
ai.tts_lite_1k_chars | Spectre Lite TTS | 1,000 characters | ₹4.00 | 50 |
ai.tts_pro_1k_chars | Spectre Pro TTS | 1,000 characters | ₹5.50 | — |
ai.llm_1k_in_nano | LLM input — Nano | 1,000 tokens | ₹0.01 | 500 |
ai.llm_1k_out_nano | LLM output — Nano | 1,000 tokens | ₹0.04 | 100 |
ai.llm_1k_in_flash | LLM input — Flash | 1,000 tokens | ₹0.03 | — |
ai.llm_1k_out_flash | LLM output — Flash | 1,000 tokens | ₹0.25 | — |
ai.llm_1k_in_frontier | LLM input — Frontier | 1,000 tokens | ₹0.30 | — |
ai.llm_1k_out_frontier | LLM output — Frontier | 1,000 tokens | ₹1.50 | — |
ai.tool_invocation | Tool invocation | invocation | ₹0.02 | 5,000 |
ai.kb_1k_queries | Knowledge retrieval | 1,000 queries | ₹2.00 | 10 |
Input and output are separate meters
Which model class is which
A class is a price band, not a quality ranking. Which band a model sits in is decided by what the provider charges for it, so a model can be excellent and still sit in a cheap band.
- Nano — GPT-5 nano, Gemini 2.5 Flash-Lite.
- Flash — Gemini 2.5 Flash, Gemini 3.1 Flash-Lite, GPT-5 mini. The Standard stack's default.
- Frontier — Claude Haiku 4.5, Gemini 3.5 Flash, Claude Sonnet 5. The Premium stack's default.
Opus-class models are bring-your-own-key
Which models your plan can reach
Two things decide it: whether the provider is included on your plan, and whether the model's band is within your plan's ceiling. Free reaches up to the Flash band; every paid plan reaches Frontier. Above that — or on a provider your plan does not include — connect your own key, and you pay that vendor directly while Converse charges only the agent runtime.
The agent form shows models your plan cannot use, greyed out with the reason, rather than hiding them. The decision is made server-side: the API refuses a disallowed model with a 403, and a database trigger refuses it again beneath that, so it holds no matter which client or key made the request.
# What this workspace can use, and why anything else cannot curl -H "Authorization: Bearer $CONVERSE_API_KEY" \ "https://<project>.supabase.co/functions/v1/models?include=all"
{
"groups": [
{ "key": "converse", "label": "Converse", "available": 3 },
{ "key": "google", "label": "Google Gemini", "available": 11,
"note": "Served from our Vertex AI project." },
{ "key": "anthropic", "label": "Anthropic Claude", "available": 4,
"note": "Served from our Vertex AI project." },
{ "key": "openrouter", "label": "Others", "available": 180,
"note": "Everything else, via OpenRouter." }
],
"models": [
{ "id": "gemini-2.5-flash", "provider": "google", "kind": "llm",
"route": "vertex", "source": "plan", "band": "flash", "allowed": true },
{ "id": "claude-opus-5", "provider": "anthropic", "kind": "llm",
"route": "vertex", "source": "plan", "band": "byok_only", "allowed": false,
"reason": "claude-opus-5 costs more per token than any platform rate covers. Add your own anthropic key to use it." }
]
}Model lists are never hardcoded — each provider is asked for its own current catalogue, so a model is available here the day the vendor ships it. The Others group is everything reachable through OpenRouter, minus anything Google, OpenAI or Anthropic sell directly, since those have their own sections and listing them twice would offer the same model on two different bills.
Telephony
Carrier minutes are passed through at cost on every plan, including pay-per-second — the voice rate covers the AI side of a call, never the carriage. The rate includes both the carrier leg and the SIP media leg between the carrier and your agent.
| Meter key | Name | Unit | Rate | Free / mo |
|---|---|---|---|---|
telephony.pstn_minute | PSTN minutes | minute | ₹1.00 | — |
telephony.did_month | Phone number (DID) | number-month | ₹300 incl. GST | — |
Channels
WhatsApp is priced by Meta's own conversation categories, because that is how Meta bills. Service replies inside a user-initiated 24-hour window carry no Meta charge and are free here too. You supply your own Meta WhatsApp Business account.
| Meter key | Name | Unit | Rate | Free / mo |
|---|---|---|---|---|
channel.whatsapp_marketing | WhatsApp — marketing | message | ₹0.95 | — |
channel.whatsapp_utility | WhatsApp — utility | message | ₹0.15 | — |
channel.whatsapp_auth | WhatsApp — authentication | message | ₹0.15 | — |
channel.whatsapp_service | WhatsApp — service | message | Free | — |
channel.sms_out | SMS — outbound | message | ₹0.70 | — |
channel.sms_in | SMS — inbound | message | ₹0.10 | — |
Platform
| Meter key | Name | Unit | Rate | Free / mo |
|---|---|---|---|---|
platform.storage_gb_month | Storage | GB-month | ₹8.00 | 1 |
Provider pass-through
The pay-as-you-go plan passes model tokens through at provider list price, and the rate card we pay is published so you can check that. It also lets you size a bring-your-own-key bill before committing to one.
curl https://<project>.supabase.co/functions/v1/pricing/providers
{
"fx": { "usd_inr": 95.24, "as_of": "2026-08-10" },
"providers": [
{
"key": "llm.google.gemini_25_flash",
"provider": "Google",
"product": "Gemini 2.5 Flash",
"service": "llm",
"unit": "1,000 tokens",
"rate_in_inr": 0.02857,
"rate_out_inr": 0.2381,
"source_amount": "$0.30 / $2.50 per 1M",
"source_url": "https://ai.google.dev/gemini-api/docs/pricing",
"byok": true
}
]
}Rates carrying rate_in_inr and rate_out_inr are language models, priced per direction. Everything else uses the single rate_inr field. fx.usd_inr is the rate every USD-denominated figure was converted at, so you can tell a repricing from a rupee movement.
The pricing API
Unauthenticated — it is the price list on the website. Nothing organisation-specific is served here.
GET /pricing— the whole catalogue: meters, plans, free allowances, provider rates, GST rate and FX basis.GET /pricing/plans— plans only, with rates fully resolved.GET /pricing/providers— the third-party rate card.GET /pricing/quote— what a workload would cost.
Responses carry an ETag derived from the catalogue version and are cached for five minutes at the edge, so a page that reloads on every navigation costs one 304.
Quoting a workload
curl "https://<project>.supabase.co/functions/v1/pricing/quote\ ?plan=per_second&stack=standard&minutes=10000&telephony=true"
plan—per_second,freeorstartup. Defaults toper_second.stack—standardorpremium. On component plans this selects the TTS engine and LLM class.liteis accepted and resolves to Standard.minutes— connected minutes per month. Defaults to 1,000.telephony—falsefor web and in-app sessions, which have no carrier leg.
The response itemises each meter, subtotal, GST and an effective per-minute figure, alongside the usage assumptions it applied. Those assumptions — roughly 850 characters of speech and 8,000 input plus 350 output tokens per connected minute — are the same ones the published rates were set from. Your own agents will differ; the response says so.
Reading a charge back to a call
Every charge writes an append-only row to usage_events carrying the meter, the quantity, the rate in force at the time, what an allowance absorbed, and the ref_id of the call that caused it. An invoice is only as good as the events behind it, so those rows are never updated and never deleted — and a rate change closes the old row with an effective_to rather than editing it.
