The REST API is what your backend uses to talk to Livqeno: to create
rooms and conversations, mint tokens, and read what happened. The server SDKs
(@livqeno/server, livqeno) call it for you. You only call it
directly if your backend is in another language, or you're debugging with
curl.
These rules apply to every endpoint. Read this page once, and the endpoint pages will make sense.
Base URL
Every endpoint starts with /v1:
https://api.livqeno.com/v1/...
Your backend reads this from LIVQENO_API_URL. If you don't set it, the SDKs
use http://localhost:4100. That only works for a local mock or proxy, so
always set it.
Authentication
Every request from your backend carries your project API key. Send it as a bearer token:
curl "$LIVQENO_API_URL/v1/rooms" \
-H "Authorization: Bearer $LIVQENO_API_KEY"- A key looks like
rvk_<env>_<id>.<secret>.<env>isdev,stg, orprod. - Each key is tied to one environment on our side. A development key can never reach production data.
- The
<env>part is only a label for you to read.
More: API keys.
Errors
Every error looks like this:
{
"code": "RAVEN_ROOM_NOT_FOUND",
"legacyCode": "NOT_FOUND",
"message": "Room not found",
"requestId": "req_d4a74eaeb970633fc42414a6",
"path": "/v1/rooms/2f1b6c3e-8d4a-4b7e-9c21-5a0e7d3f9b10"
}A validation error (RAVEN_VALIDATION_FAILED, 400) has two extra
fields, statusCode and error. Its message can be a list, with one
entry per bad field:
{
"message": ["environment must be one of the following values: DEVELOPMENT, STAGING, PRODUCTION"],
"error": "Bad Request",
"statusCode": 400,
"code": "RAVEN_VALIDATION_FAILED",
"legacyCode": "VALIDATION_FAILED",
"requestId": "req_7f9f475ddcab0cb6f554f253",
"path": "/v1/projects/…/api-keys"
}How to handle errors:
- Check
code. That's the reliable field. messagecan be a string or a list of strings (string | string[]).- Don't use
legacyCode. It is old and will be removed. - Some errors add fields. For example, a 429 adds
retryAfterSeconds. Ignore fields you don't know. - Ids in the URL are UUIDs. A badly formed id gets a 400, not a 404.
Every error code is listed in Errors.
Request ids
When something goes wrong, the request id is how you and Livqeno find the
same request in the logs. Every response has an x-request-id header. Error bodies repeat it as
requestId. Include it when you report a bug.
You can also send your own id, to follow one request through your logs and ours:
x-request-id: 7c1f9e2a-your-own-correlation-id
- Your id is used only if it is 1–64 characters of
A-Za-z0-9_-. - Otherwise we make a new one.
- Our ids look like
req_plus 24 hex characters.
Safe retries (idempotency)
Networks fail. Say your backend sends "create a message" and the connection drops before the reply arrives. Did it work? If you just retry, you might post the message twice. Idempotency solves this: sending the same request again has the same effect as sending it once.
Endpoints that create a token or a message accept an Idempotency-Key
header. If you retry with the same key, you get the first response back.
The work is not done twice.
curl -X POST .../v1/rooms/$ROOM_ID/rtc-tokens \
-H "Authorization: Bearer $LIVQENO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H 'Content-Type: application/json' \
-d '{"participantIdentity":"user-42","permissions":{"join":true,"subscribe":true}}'For token creation, the replay window is only 5 minutes. A token can expire in as little as 30 seconds, so a longer window could hand back a dead token.
The endpoint pages show which endpoints support this. More: Idempotency.
Pagination
You'll use this when loading older messages, for example as a user scrolls up in a chat window. Chat message history uses cursors, not page numbers. A cursor is an opaque marker that means "continue from here":
GET /v1/chat/conversations/{room}/messages?limit=50
GET /v1/chat/conversations/{room}/messages?before=<cursor>
- Read
nextCursorfrom the response. - Pass it back to get the next page.
Don't build or edit a cursor yourself. A broken cursor returns
RAVEN_INVALID_CURSOR. It never quietly restarts at page one. More:
Message history.
Environments
- Endpoints you call with an API key take no
environmentparameter. The key decides. - Dashboard endpoints (with a login session) accept
?environment=. The default is development.
More: Environments.
Rate limits
Some endpoints have a rate limit. The endpoint pages show each limit. Rate limits explains how they are counted and how to handle a 429.
Next steps
- RTC API: the first endpoints most backends call — create a room, mint a token.
- All endpoints: every endpoint on one page.
- Authentication: which credential to use.
- Errors: every error code.