Usage Queries and Quota Limits
Usage endpoints, metering granularity, concurrency quota, hard limits and over-limit behaviour.
This page does one thing: it lists the hard limits, so you do not discover them during load testing. Every number is enforced by the service (the component is named in parentheses); none of it is an "approximately" statement from the docs.
Project-level quotas (adjustable in the console)
| Quota | Default | Upper bound | Response when exceeded | Where it is enforced |
|---|---|---|---|---|
| Concurrent recording jobs | 5 | 1000 | 429 recording_quota_exceeded (details.limit/details.active) | the tenancy and recording services |
| Concurrent streaming jobs (shared by Media Push / bypass streaming / cloud transcoding) | 5 | 1000 | 429 streaming_quota_exceeded | the media push, streaming and cloud transcoding services |
| Channel count cap | 0 (unlimited) | 1,000,000 | 503 no_server_resources (message: project channel quota exceeded) | the token service |
How to adjust: POST /console/projects/{projectId} (quotas.recordingConcurrent / streamingConcurrent / maxChannels), or the project settings page in the console. Setting 0 means unlimited (only maxChannels supports 0).
Product-level hard limits (code constants, not adjustable)
| Limit | Value | Notes |
|---|---|---|
| Converters per project | 500 | Media Push (CONVERTER_QUOTA) |
| Cloud players per project | 500 | Media Pull (PLAYER_QUOTA) |
| Stream templates per project | 10 | Media Gateway (TEMPLATE_LIMIT) |
| builderToken validity | 5 minutes, single use | cloud transcoding (expired/reused/unknown → 401 invalid_token; acquire a fresh token and retry) |
| Recording resourceId lease | 30-second TTL | you must start within that window after acquire |
Request-level rate limiting
| Item | Default | Environment variable |
|---|---|---|
| Requests per caller per minute | 600 | NIMEET_RATE_LIMIT_PER_MINUTE |
| Burst bucket capacity | 60 | NIMEET_RATE_LIMIT_BURST |
| Disable rate limiting | NIMEET_RATE_LIMIT=off | testing environments only |
Over the limit returns 429 + a Retry-After header (seconds) and details.retryAfterSeconds / details.limitPerMinute / details.burst. The rate-limit key is derived from the credential and the source (rateLimitKey), so different projects of the same customer share one bucket — do not try to brute-force past it; just back off.
Field-level limits
| Field | Limit | Response when exceeded |
|---|---|---|
channelName | 1–128, [A-Za-z0-9_-] | 400 invalid_channel_name |
uid | integer from 1 to 2147483647 | 400 invalid_parameter |
ttlSeconds | ≥ 60, finally clamped by the project's tokenTtlSeconds | 400 invalid_parameter |
list page_size | 1–500, default 100 | 400 invalid_parameter |
| write requests | must be Content-Type: application/json | 415 unsupported_media_type |
Usage queries
# Usage and amount for the current project over a time window
curl -s "$NIMEET_API_BASE/v1/analytics/usage?from=$FROM&to=$TO&granularity=day" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC"
# Real-time monitoring (last 30 minutes, 1-minute buckets)
curl -s "$NIMEET_API_BASE/v1/analytics/realtime" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC"Metric definitions and alarm thresholds are in Crystal Ball; unit prices and the billing formula are in Billing model.
What to do when you hit a limit
| Scenario | Error code | Action |
|---|---|---|
| Concurrent jobs at the cap | recording_quota_exceeded / streaming_quota_exceeded | queue and retry (exponential backoff), or raise the quota; do not retry immediately |
| Too many requests | rate_limited | back off according to Retry-After |
| Channel cap reached | no_server_resources (503) | clean up old channels or raise maxChannels |
| builderToken expired | token_invalid | request a new one on the spot |