Billing Model and Unit Prices
Per-minute billing dimensions (audio/video, recording, streaming, transcoding), unit prices, metering and free quota.
ni-meet bills per minute (not per peak, not per seat): every kind of usage produces a UsageEvent, minutes are accumulated, and the total is multiplied by the unit price.
Billing dimensions
| Type | What is metered | Default unit price (USD / 1000 minutes) | Free tier (minutes) |
|---|---|---|---|
audio | audio call duration | 0.99 | 10,000 |
video | video call duration | 3.99 | 10,000 |
recording | cloud recording duration | 7.99 | 0 |
streaming | streaming (Media Push) duration | 2.99 | 0 |
transcoding | cloud transcoding duration | 4.99 | 0 |
The formula (identical to the implementation):
amount(type) = max(0, minutes(type) - freeMinutes(type)) / 1000 * unitPricePerThousandMinutes(type)
billAmount = Σ amount(type) // free minutes are deducted per type, not sharedFree tiers are deducted per type: the 10,000 audio minutes and the 10,000 video minutes are two separate allowances, not one shared 10,000.
Where a minute comes from
| Event | When it is recorded |
|---|---|
| Participant joins → leaves | accumulated from the participant's online time in that channel (UsageEvent.minutes) |
| Recording job running → stopped | from the job's runtime |
| Streaming converter running → stopped | from the streaming duration |
| Transcoding job running → destroyed | from the job's runtime |
Details of the model:
- minutes are floating point, rounded to 2 decimals when the total is aggregated (
round(minutes, 2)); - the same person joining and leaving the same channel repeatedly accumulates; it is not merged into "one person";
- an empty channel (the grace period after the last participant leaves) produces no audio minutes;
- recording/streaming/transcoding bill even with no viewers — they run on separate nodes.
Querying billing data
curl -s "$NIMEET_API_BASE/v1/analytics/usage?from=2026-10-01T00:00:00Z&to=2026-10-31T23:59:59Z&granularity=day" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC"It returns buckets[] (minutes/channels/users per time bucket) and totals (minutes, peakChannels, amount, currency). granularity accepts hour / day / month. Field-level documentation is in the Crystal Ball API.
Billing differences from Agora (the most common migration question)
| Dimension | Agora | ni-meet |
|---|---|---|
| Billing unit | minutes (tiered by resolution) | minutes (two types, audio/video, no resolution tiers) |
| Free tier | 10,000 minutes per month (promotional) | configured per type, same defaults as above |
| Bill granularity | day/month | hour / day / month queries |
| Settlement | prepaid packages + postpaid | up to your deployment; we only provide usage and amount computation |
Four cost-control levers
- Resolution: video bills per minute, so lowering the resolution does not lower the minute count, but it does reduce bandwidth and transcoding cost;
- Recording mode:
composite(mixed) is cheaper thanindividual(per-stream) — one job records everyone; - Number of streaming targets: one egress job per converter, so multiple targets mean multiple streaming costs;
- Idle reclamation: set
idleTimeoutlow so jobs do not keep running after everyone has left.
End-to-end example
Call GET /v1/analytics/usage for usage and GET /v1/analytics/calls for the call list and call details; the amount in the response is computed from the unit prices on this page and the usage. Field definitions are in Analytics.