LevelChatLevelChatDocs
Error reference

Reference

Error reference

Every code LevelChat returns — REST API, SDKs, webhooks — with the HTTP status, what triggers it, and the recovery action your client should take.

Errors follow RFC 7807 Problem Details. Every response carries a code field — that is the lookup key on this page. The type URL in the envelope points at levelchat.io/errors/<code>, which redirects here to the matching anchor.

{
  "type":       "https://levelchat.io/errors/quota_exceeded",
  "title":      "Billing quota exhausted",
  "status":     402,
  "detail":     "Workspace consumed 110% of monthly minutes.",
  "code":       "quota_exceeded",
  "request_id": "req_01HZ...",
  "instance":   "/v1/rooms"
}

Authentication & authorization

Identity, tokens, scopes, SSO.

  • unauthorizedHTTP 401# permalink

    Unauthorized

    Cause. The request did not include valid credentials, or the credentials were not accepted by the server.

    Recovery. Re-fetch a fresh token via your auth provider; if you minted a JWT yourself, verify it is signed with the right secret and the `aud` claim matches your project.

  • token/invalidHTTP 401# permalink

    Token is invalid

    Cause. The JWT did not pass signature verification, was malformed, or carried claims the server rejected.

    Recovery. Re-issue the token. If you self-mint, double-check the signing algorithm and key id.

  • token/expiredHTTP 401Retryable# permalink

    Token has expired

    Cause. The token TTL has elapsed.

    Recovery. Refresh the token. SDKs retry automatically once they obtain a new one.

  • token/unauthorizedHTTP 401# permalink

    Token lacks required scopes

    Cause. The JWT was valid but did not contain the scope(s) needed for the requested action (e.g. `recording:write`).

    Recovery. Mint a token that includes the missing scope. The required scope is listed in each endpoint reference.

  • forbidden_workspace_roleHTTP 403# permalink

    Workspace role too low

    Cause. The caller is a member of the workspace but their role does not permit this action.

    Recovery. Have a workspace admin elevate the role, or call from an account that already has it.

  • forbiddenHTTP 403# permalink

    Forbidden

    Cause. Generic authorization failure — credentials were valid but access to the resource is denied.

    Recovery. Verify you own the resource and that no IP allowlist is blocking the request.

  • invite_requiredHTTP 403# permalink

    Invite required for SSO

    Cause. A user authenticated through SSO whose email is not yet provisioned in the workspace.

    Recovery. Have an admin send an invite, or enable just-in-time provisioning under Settings → Single sign-on.

  • sso_config_missingHTTP 503# permalink

    SSO not configured

    Cause. The workspace has no SSO connector wired up but the caller hit an SSO endpoint.

    Recovery. Configure SSO in Settings → Single sign-on, then retry.

  • sso_discovery_failedHTTP 502Retryable# permalink

    OIDC discovery failed

    Cause. The IdP discovery endpoint did not return a usable document.

    Recovery. Verify the issuer URL is reachable from our network and serves `/.well-known/openid-configuration`.

  • sso_email_domain_deniedHTTP 403# permalink

    Email domain not allowed by workspace

    Cause. The workspace restricts SSO to specific domains and the user does not match.

    Recovery. Add the domain to the allowlist in Settings → Single sign-on, or use a different account.

  • sso_id_token_invalidHTTP 401# permalink

    SSO id_token invalid

    Cause. The id_token returned by the IdP failed JWT validation (signature, audience, expiry).

    Recovery. Re-attempt sign-in. If the failure persists, check that the IdP and LevelChat clock skew is under 30 seconds.

  • sso_state_invalidHTTP 400# permalink

    OIDC state mismatch

    Cause. The `state` parameter returned by the IdP did not match the one we issued — possible CSRF or cookie loss.

    Recovery. Restart the SSO flow from /login. Ensure third-party cookies are not blocked for the LevelChat domain.

  • sso_token_exchange_failedHTTP 502Retryable# permalink

    Authorization code exchange failed

    Cause. The IdP rejected the authorization code we sent to its token endpoint.

    Recovery. Verify the OIDC client_id, client_secret, and redirect_uri configured in the workspace match the IdP.

  • sso_user_not_provisionedHTTP 403# permalink

    SSO user not provisioned

    Cause. The user authenticated successfully but is not present in the workspace and JIT provisioning is disabled.

    Recovery. Enable JIT provisioning, or pre-provision the user via SCIM.

  • email_unverifiedHTTP 403# permalink

    Email not verified

    Cause. The account exists but the verification link has not been clicked.

    Recovery. Re-send the verification email from /verify-email; the action will succeed after click-through.

Validation

Malformed input the server refused to process.

  • bad_requestHTTP 400# permalink

    Malformed request

    Cause. The request body did not match the endpoint schema (missing required field, wrong type, etc.).

    Recovery. Check the endpoint reference; the `detail` field of the response identifies which field failed validation.

  • config/invalidHTTP 400# permalink

    SDK configuration invalid

    Cause. The SDK was constructed with an invalid options object — e.g. unknown region, malformed signaling URL.

    Recovery. Compare your `new LevelChatClient({...})` call against the SDK reference; the SDK error message names the bad field.

  • config/missing-api-keyHTTP 400# permalink

    SDK missing API key

    Cause. The SDK was constructed without an `apiKey` (or a `tokenProvider`).

    Recovery. Provide either an `apiKey` (server-side use only) or a `tokenProvider` callback (browser use).

  • invalid_identityHTTP 400# permalink

    Identity malformed

    Cause. The `identity` field is missing, empty, or exceeds the 128-character limit.

    Recovery. Pass a stable, non-empty string ≤128 chars.

  • invalid_roleHTTP 400# permalink

    Role not recognized

    Cause. The role string was not one of {owner, admin, member, viewer}.

    Recovery. Use one of the four supported role values, lowercase.

  • invalid_roomHTTP 400# permalink

    Room ID malformed

    Cause. The room ID failed format validation (alphanumeric + dash, 4–64 chars).

    Recovery. Generate room IDs server-side or rely on `client.rooms.create()` which returns a valid one.

  • unknown_tierHTTP 400# permalink

    Billing tier not recognized

    Cause. A billing-tier identifier was passed that does not match any active plan.

    Recovery. Re-fetch the plan list from `/v1/billing/plans` and use one of the returned `id` values.

Rate limits & quotas

You are being throttled or have run out of budget.

  • rate_limitedHTTP 429Retryable# permalink

    Rate limited

    Cause. You exceeded the per-endpoint rate budget. The response carries `Retry-After` and `X-RateLimit-Reset` headers.

    Recovery. Honor `Retry-After` and back off. SDKs do this automatically with jitter.

  • network/rate-limitedHTTP 429Retryable# permalink

    SDK saw 429 from API

    Cause. SDK-side wrapper for the server `rate_limited` code.

    Recovery. Same as `rate_limited` — let the SDK retry with backoff.

  • quota_exceededHTTP 402# permalink

    Billing quota exhausted

    Cause. The workspace consumed its plan allowance (participant-minutes, storage, or recordings) for the current cycle.

    Recovery. Upgrade the plan, add overage capacity in Settings → Billing → Overage, or wait for the cycle to reset.

  • room/cap-deniedHTTP 429# permalink

    Room participant cap reached

    Cause. A new join was attempted on a room that is already at its concurrent-participant ceiling.

    Recovery. Free a slot, request a higher cap from sales for that workspace, or open a second room.

Not found

The resource does not exist, or your token cannot see it.

  • not_foundHTTP 404# permalink

    Resource not found

    Cause. The path resolved to no resource owned by this workspace.

    Recovery. Verify the ID; remember resources are workspace-scoped so a token from workspace A cannot see workspace B.

  • room_not_foundHTTP 404# permalink

    Room does not exist

    Cause. The room ID was well-formed but no room with that ID is open or recently closed (24h retention).

    Recovery. Create the room first via `client.rooms.create()` or pre-create it server-side.

  • not_a_memberHTTP 404# permalink

    User not a member of workspace

    Cause. A user-scoped action referenced a user who is not a current member of the calling workspace.

    Recovery. Invite the user, or use their workspace-scoped identity instead of their global account id.

  • recording_not_readyHTTP 404Retryable# permalink

    Recording still processing

    Cause. A recording was requested whose post-processing pipeline has not finished yet.

    Recovery. Poll the recording with exponential backoff, or subscribe to the `recording.completed` webhook.

Conflict

Your request collided with an invariant on the resource.

  • conflictHTTP 409# permalink

    State conflict

    Cause. The request would have violated a uniqueness or ordering invariant on the resource.

    Recovery. Re-read the current state and reconcile before retrying.

  • external_id_takenHTTP 409# permalink

    external_id already in use

    Cause. You supplied an `external_id` that another resource in this workspace already owns.

    Recovery. Either delete the old resource that owns the id, or pick a new id.

  • slug_takenHTTP 409# permalink

    Workspace slug already in use

    Cause. The slug you proposed is already taken by another workspace.

    Recovery. Pick a different slug. Reserved patterns (admin, api, www, …) are also rejected here.

  • node_existsHTTP 409# permalink

    SFU node already registered

    Cause. A self-hosted SFU node tried to register with an id that another active node already owns.

    Recovery. Generate a fresh node id, or de-register the stale node first.

  • invitation_invalidHTTP 409# permalink

    Invitation invalid

    Cause. The invite token has been used already, expired, or was revoked.

    Recovery. Request a fresh invite from a workspace admin.

Server & dependencies

5xx — the server, an upstream, or maintenance.

  • internal_errorHTTP 500Retryable# permalink

    Internal server error

    Cause. An unexpected condition prevented the request from completing. The incident is logged with `request_id`.

    Recovery. Retry once. If it recurs, file a ticket with the `request_id` from the response.

  • bad_gatewayHTTP 502Retryable# permalink

    Bad gateway

    Cause. An upstream service returned a non-2xx response that we could not interpret.

    Recovery. Retry with backoff.

  • upstream_unreachableHTTP 502Retryable# permalink

    Upstream service unreachable

    Cause. A required dependency (billing, license, signaling) failed to respond within the deadline.

    Recovery. Retry with backoff; the SDK does this automatically.

  • upstream_request_failedHTTP 502Retryable# permalink

    Upstream returned malformed response

    Cause. A dependency replied but the payload did not match the contract.

    Recovery. Retry. Persistent failures indicate a contract drift — please file a ticket.

  • service_unavailableHTTP 503Retryable# permalink

    Service unavailable

    Cause. The service is in maintenance or a critical dependency is degraded. Status page reflects ongoing incidents.

    Recovery. Honor `Retry-After`. Consult status.levelchat.io for the live incident.

  • room_check_failedHTTP 503Retryable# permalink

    Room health check failed

    Cause. The SFU pool failed its periodic self-check and is temporarily refusing new rooms.

    Recovery. Retry in 30s. The control plane will route around the unhealthy node.

  • onprem_disabledHTTP 503# permalink

    Feature disabled in self-hosted

    Cause. A managed-only capability (e.g. AI transcription) was called against a self-hosted deployment.

    Recovery. Either enable the feature in your license, or use a managed workspace for the call.

  • auth_unconfiguredHTTP 503# permalink

    Auth service URL not set

    Cause. The control plane was deployed without `AUTH_SERVICE_URL` and cannot resolve identities.

    Recovery. Operator action: set the env var in your deployment and restart admin-api.

  • scim_store_unconfiguredHTTP 503# permalink

    SCIM store unavailable

    Cause. SCIM endpoints were called but the backing store is not configured.

    Recovery. Operator action: configure the SCIM store URL in workspace settings.

  • sso_store_unconfiguredHTTP 503# permalink

    SSO store unavailable

    Cause. SSO endpoints were called but the backing store is not configured.

    Recovery. Operator action: configure the SSO store URL in workspace settings.

Business logic

Domain rules that say no even though the request is well-formed.

  • contact_sales_onlyHTTP 403# permalink

    Feature requires sales contact

    Cause. The requested feature is gated behind a sales-only conversation (e.g. on-premise license, custom SLA).

    Recovery. Reach out to sales@levelchat.io — they can grant the entitlement on your workspace.

  • billing_unconfiguredHTTP 503# permalink

    Billing not configured

    Cause. A workspace tried to consume billable resources before completing billing setup.

    Recovery. Add a payment method or accept the free-tier terms under Settings → Billing.

  • license_revokedHTTP 403# permalink

    License revoked

    Cause. The on-premise license attached to this deployment has been revoked or has expired.

    Recovery. Renew the license via sales, then restart the affected services to pick up the new key.

  • signup_disabledHTTP 403# permalink

    Signups closed

    Cause. The workspace has disabled open signups for new users.

    Recovery. Have an admin invite the user explicitly, or re-enable open signups in Settings.

  • no_valid_recipientsHTTP 400# permalink

    Webhook has no valid endpoints

    Cause. A webhook dispatch was attempted but no enabled endpoints matched the event type.

    Recovery. Add a webhook endpoint for that event in Settings → Webhooks.

  • node_revokedHTTP 410# permalink

    SFU node revoked

    Cause. The SFU node was de-provisioned by an admin and is no longer accepting traffic.

    Recovery. Re-provision the node, or route to a different healthy node.

  • parent_revokedHTTP 410# permalink

    Parent resource revoked

    Cause. A dependent resource is being requested whose parent (workspace, project) was deleted or suspended.

    Recovery. Restore or replace the parent before retrying.

Media (camera, mic)

Browser-side permissions and device errors. SDK-only.

  • media/permission-deniedSDK only# permalink

    Media permission denied

    Cause. The browser blocked getUserMedia — either the user clicked "Block" or the page is in an insecure context.

    Recovery. Re-prompt with a UI that explains why the permission is needed, or send the user to browser settings.

  • media/device-not-foundSDK only# permalink

    Media device not found

    Cause. The requested camera or microphone deviceId is offline (unplugged, OS-disabled).

    Recovery. Refresh the device list with `navigator.mediaDevices.enumerateDevices()` and offer the user a picker.

  • media/unsupportedSDK only# permalink

    Media constraint unsupported

    Cause. The browser does not support the requested constraint (e.g. `frameRate: 60` on Safari iPad).

    Recovery. Fall back to a permissive constraint shape and let the browser pick.

  • media/constraint-not-satisfiedSDK only# permalink

    Constraint not satisfied

    Cause. The chosen device cannot meet the constraint (e.g. requested 4K on a 1080p webcam).

    Recovery. Loosen the constraint or pick a different device.

Signaling

Control-plane websocket and RPC errors. SDK-only.

  • signaling/connect-failedSDK onlyRetryable# permalink

    Signaling connection failed

    Cause. The WSS handshake to the signaling tier did not complete.

    Recovery. Verify network egress to *.signaling.levelchat.io:443 is open; SDK auto-retries with backoff.

  • signaling/closedSDK onlyRetryable# permalink

    Signaling connection closed

    Cause. The signaling socket dropped after being connected.

    Recovery. SDK reconnects automatically; surface a transient "reconnecting" UI to the user.

  • signaling/timeoutSDK onlyRetryable# permalink

    Signaling frame timeout

    Cause. A request frame received no response within the deadline.

    Recovery. SDK retries on a fresh socket; treat as transient.

  • signaling/protocolSDK only# permalink

    Signaling protocol error

    Cause. A signaling frame failed to decode — usually a version mismatch.

    Recovery. Upgrade your SDK to a version compatible with the platform release.

  • signaling/rpc-errorSDK onlyRetryable# permalink

    Signaling RPC failed

    Cause. The SFU rejected the RPC (e.g. publish a track that the room policy disallows).

    Recovery. Inspect the inner error code in the SDK error object and adjust the call accordingly.

  • signaling/rpc-timeoutSDK onlyRetryable# permalink

    Signaling RPC timed out

    Cause. The SFU did not acknowledge the RPC in time.

    Recovery. SDK retries automatically; if it persists, the SFU may be under load.

WebRTC transport

ICE, DTLS, codec and browser-support errors. SDK-only.

  • transport/ice-failedSDK onlyRetryable# permalink

    ICE negotiation failed

    Cause. WebRTC could not establish a candidate pair — typically a strict firewall blocking UDP and TURN/443 fallback.

    Recovery. Verify UDP egress to *.media.levelchat.io is open, or that TURN over 443 is reachable; SDK auto-retries.

  • transport/dtls-failedSDK onlyRetryable# permalink

    DTLS handshake failed

    Cause. WebRTC DTLS handshake did not complete after ICE succeeded.

    Recovery. Usually a transient network condition; SDK retries the negotiation.

  • transport/unsupportedSDK only# permalink

    WebRTC not supported

    Cause. The browser does not expose WebRTC APIs at all (very old or stripped builds).

    Recovery. Show a "browser not supported" message linking to the supported-browsers doc.

  • codec/unsupportedSDK only# permalink

    Codec not supported

    Cause. The room is locked to a codec the browser cannot encode or decode (e.g. AV1 on older Safari).

    Recovery. Either widen the room's allowed-codec list, or upgrade the user's browser.

Recording

Recording permission and pipeline errors.

  • recording/not-permittedSDK only# permalink

    Recording not permitted

    Cause. Recording was requested in a room whose policy disallows it (or by a user without `recording:write`).

    Recovery. Adjust the room policy or token scopes.

  • recording/backend-failedSDK onlyRetryable# permalink

    Recording backend failed

    Cause. The recording pipeline could not start or persist the artifact.

    Recovery. SDK reports the failure to the room; the next recording attempt will pick a fresh backend.

End-to-end encryption

E2EE-specific failures on the wire.

  • encryption/key-missingSDK only# permalink

    E2EE key missing

    Cause. An encrypted frame was received but the corresponding decryption key has not arrived yet.

    Recovery. SDK buffers a short grace period; if keys never arrive, the publisher likely has a key-distribution bug.

  • encryption/unsupportedSDK only# permalink

    E2EE not supported

    Cause. The browser lacks `RTCRtpScriptTransform` / Insertable Streams support required for E2EE.

    Recovery. Disable E2EE for that browser, or upgrade the user to a Chromium-based browser.

Saw a code that is not on this page?

That is a bug on our side — every code we emit must be documented here. Please open an issue with the offending request_id so we can find the log line and add the entry.