Billing
Billing
The call rate#
GET /console/v2/billing/rate returns the rate on its own: rate_nano_usd_per_minute: "5000000" ($0.005 per connected minute — half a cent), metering_basis: "connected_minute_rounded_up", and a rate_version. Every call rounds up to the next full minute. Cost is ceil(connected_seconds / 60) × rate in integer nano-USD; a 59-second call costs $0.005 (1 minute), a 61-second call costs $0.01 (2 minutes), and a 10-minute call costs $0.05.
Read the rate from this route rather than hard-coding it. A published rate change is a new rate_version; sessions already admitted keep the version they froze.
Pure pay as you go#
There is no monthly platform fee, no minimum spend, no seat fee, no commitment, and no contract. You top up a prepaid wallet with whatever amount you want, you spend what you use, and whatever is left stays yours.
A new account gets a one-time welcome credit of $1 (₹50 on a rupee wallet) when its email is verified. It pays Dvaarik's own per-minute and per-reply fees, never your AI or carrier bills, and the Money page lists it as "Welcome credit".
Two things are metered: connected voice minutes, and AI chat replies at ₹0.05 or $0.0005 each (Chat agents), from the same wallet, charged once a reply is delivered. Meta's and Telegram's own charges, if any, are billed to you by them. Dvaarik charges nothing for:
- creating projects, agents, or API keys;
- the console;
- the SDKs (
@dvaarikai/node,dvaarik,@dvaarikai/web); - webhook delivery, retries, and dead letters;
- the playground, beyond its own connected minutes — a playground call is a real call, billed at the same rate as any other;
- post-call analysis. Insights run on your model under your provider account, so that provider bills you for those tokens and Dvaarik adds nothing on top;
- messages people send to a chat agent, and chat replies that were refused, never sent or may not have arrived (a reply Telegram or Meta accepted stays charged even if it is later reported undelivered). Your own AI account bills the tokens of every reply; we add nothing to them.
GET /console/v2/billing/summary?project_id=… returns the account wallet — balance_nano_usd, held_nano_usd, spendable_nano_usd, lifetime_topup_nano_usd, low_balance_threshold_nano_usd, low_balance — together with the rate and the project's concurrency, request-rate, and maximum-session limits. The wallet belongs to the account; it is reported against one project.
Holds and settlement#
A session places a hold for its maximum duration when admitted. It is refused with 402 when the spendable balance cannot cover that hold. When the session ends, the hold is released and the connected seconds are settled exactly once. GET /console/v2/billing/transactions?limit=50&offset=0 lists the ledger newest first; amount_nano_usd is null on archival rows from before USD.
Top up#
1. GET /console/v2/billing/quote?amount_minor=2500 — in the wallet's currency (cents for a dollar wallet, paise for a rupee wallet; amount_usd_cents is still accepted for dollars). The typed amount is exactly the credit (one cent = 10,000,000 nano-USD; one paisa = one paisa); a payment fee is added on top, 5% for dollars and 3% for rupees, rounded up: credits_minor, fee_minor, total_minor. Bounds are $10 to $2,000 or ₹500 to ₹2,00,000. 2. POST /console/v2/billing/topup with { "amount_minor", "project_id" } creates a Razorpay order for the total and records it first; the response carries order_id and razorpay_key_id, which the console hands to Razorpay Checkout. 502 means the gateway did not create an order; 503 means the order could not be recorded and no checkout was returned. 3. The payment webhook credits the wallet. The console polls the summary until lifetime_topup_minor grows; a successful Checkout alone is never treated as credit.
Rupees or dollars#
A wallet is in one currency: currency on the summary. Calls bill ₹0.50 or $0.005 per connected minute, whole minutes rounded up, the same rule both ways. PUT /console/v2/billing/currency with { "currency": "INR" } (or "USD") switches whenever no call holds money (can_switch_currency). Money is never converted: each currency keeps its own balance (other_currency, other_currency_balance_minor name the one not in use), and a call already running keeps the currency it started in. Amounts in the wallet's own unit are the *_minor fields (balance_minor, cost_minor, ...); the *_nano_usd fields keep describing dollars only and are null on a rupee call.
Whether international cards are accepted depends on Razorpay international-payment enablement for the Dvaarik merchant account; the console reports the gateway's answer rather than assuming it.
Receipts#
GET /console/v2/billing/invoices lists receipts for paid top-ups; GET /console/v2/billing/invoices/{invoice_id}.pdf returns the PDF. A receipt exists only once a payment has landed.
What we store#
Storage is not a line on your bill here, because there is almost nothing of yours on our disks.
Call recordings live in your own phone company's account. When an agent has record_calls enabled, Dvaarik asks your carrier to record the call. The audio is written into your own carrier account under your own carrier plan. Dvaarik stores only the carrier's reference to that recording, so you fetch the audio from your carrier with your own credentials. We pay nothing to store it, and you are not charged twice for storing it.
Browser calls have no recording. A browser call has no carrier in the path, so there is no carrier to record it and no recording reference on the call.
Transcripts live in the Dvaarik database for 90 days and are then deleted. store_transcript controls whether one is written at all; retention_days cannot extend a transcript past that 90-day window. Pull anything you need to keep — through the API or your call webhook — inside it.
The insight block survives the transcript. The short post-call summary produced by insight_config stays on the call record after the transcript is deleted: it is small, and it is your business record of what the call was about. It is generated on your own model, on your own provider account.
Everything else we keep, for how long, and how to remove it, is listed in plain words on Your data.
Estimate the per-minute cost before you build#
The platform fee is exact and published — $0.005 per connected minute, rounded up to the next minute. What you cannot know from this API alone is what your *chosen* speech, language-model, voice, or realtime provider will charge for that same minute, because that is billed by them, on your account, at whatever rate you negotiated.
The console's cost-estimate card (agent create/edit, the agent list, and the pricing calculator) renders a breakdown — Listen / Think / Speak or Realtime, your carrier's rate typed in by hand, and the platform fee — from a small table of public list prices in src/lib/providerListPrices.ts, dated and sourced per provider. It is always an estimate: only the platform fee row is exact, computed from the same nano-USD constants as the rest of this page; every provider row can drift the moment that provider changes its own price list.
Use one project per boundary
Provider secrets stay encrypted and project API keys stay on your server.