livqenoDocs

ResourcesRate limits

Rate Limits

Which endpoints are limited, how the limit is counted, and what to do on a 429.

A rate limit caps how many requests you can make in a time window. It protects Livqeno, and your project, from runaway loops and leaked keys.

You mostly meet rate limits in one place: your backend minting tokens. For example, if 100 students click "Join class" at 9:00, your backend makes 100 token requests in a few seconds with the same API key. This page tells you whether that fits, and what to do when it doesn't.

The window is 60 seconds by default (RATE_LIMIT_WINDOW_SECONDS).

Limited endpoints

These are the limits on endpoints your backend calls:

EndpointRequests per windowWhen your backend calls it
POST /v1/rooms/{roomId}/rtc-tokens60Each time a user joins a call
DELETE /v1/rooms/{roomId}/rtc-tokens/{tokenId}60When you revoke a token
POST /v1/live-streams30When a host schedules or starts a stream
POST /v1/live-streams/{streamId}/hosts60When you add a host or co-host
POST /v1/live-streams/{streamId}/viewer-tokens120Each time a viewer opens a stream

The Limits & quotas page has the same table, generated from the code.

Who the limit counts against

Livqeno counts requests against the most specific identity it has, in this order:

  1. The API key. Each key has its own limit. Two keys in one project don't share it, so one busy (or leaked) key can't use up another's.
  2. The logged-in user, for dashboard endpoints.
  3. The IP address, only when there's no identity yet (like sign-up and login).

Once there is an identity, the IP address is not used. So:

  • Someone switching IPs is still one identity, and still limited.
  • Many real users behind one office network don't share one limit.

Handling a 429

When you go over, the request fails with HTTP 429 and this body:

{
  "code": "RAVEN_RATE_LIMITED",
  "message": "Too many requests — please try again later",
  "retryAfterSeconds": 42,
  "requestId": "req_9f2c41ab77e0c3d5b1a4e8f2"
}

On your backend:

  1. Wait for retryAfterSeconds, then retry. Don't use a fixed delay.
  2. If your user is waiting (for example, on a "Joining…" screen), keep them on that screen while you wait, instead of showing an error.

If you hit the limit often during normal use, look at your join flow. A common cause is minting a new token on every page render instead of once per join.

Chat and signaling have their own limits

These limits apply to your users' apps, not your backend:

  • Chat limits sending, reacting, typing, subscribing, and connecting. They count per user, because a chat token always has one.
  • RTC signaling (the connection an app opens to join a call) limits new WebSocket connections per IP. This check happens before the token is read, so there's no identity yet.

For the close code a chat limit produces, see WebSocket Protocol.

Next steps

  • Limits & quotas: every limit, with its default.
  • Errors: what RAVEN_RATE_LIMITED and the WebSocket close codes mean.