An environment is a fully separate copy of your project's data and keys. It lets you test new code without any risk to real users. For example, your team can try a new chat feature in staging while real customers keep chatting in production, and neither can see the other's rooms, messages, or events.
This matters as soon as you have more than one deployment of your backend (say, your laptop, a staging server, and production). Each one gets its own API key, and that key decides which environment it works in.
Every Livqeno project has three environments:
Project
├── development (the default)
├── staging
└── production
- They are fixed. You can't add a fourth.
- Their keys and data are fully separate.
What is kept separate
| Thing | Separate per environment? |
|---|---|
| API keys | ✅ Each key belongs to one environment. |
| Chat tokens | ✅ They get the environment of the key that made them. |
| Rooms | ✅ Including names. |
| Conversations | ✅ Including names. |
| Webhook endpoints | ✅ A staging endpoint never gets production events. |
| Connections, errors, usage | ✅ You can view them per environment. |
Not separate: the project itself, its name, and who manages it. Environments separate traffic, not ownership.
Create a key for an environment
You'll usually do this once per deployment: one key for your local backend, one for staging, one for production. In your terminal, with the CLI:
livqeno keys create --name backend --environment production✔ API key created for the production environment.
Save this key now. It will not be shown again.
rvk_prod_8Kd2nQxwYtLm.aG9wZXlvdWFyZWhhdmluZ2Fsb3ZlbHlkYXk
This is a production key. Keep it server-side — never in an app bundle
or a committed file.
About --environment:
- Accepted values (any case):
dev/development,stg/staging,prod/production. - Leave it out and you get development, the safest choice.
- A typo like
prdis rejected. You never get the wrong key by accident.
Tell keys apart at a glance
The environment is written into the key:
rvk_dev_8Kd2nQxwYtLm development
rvk_stg_2mNpQ4rZ7xKw staging
rvk_prod_9YtL1nB2xQcR production
This label is only for you. Livqeno looks up the real environment on its side. Editing the label changes nothing. Older keys without a label still work.
How the environment is chosen
By the credential, never by the request. There's no environment
field you can set on an API call. The key you use decides it.
- A backend with a development key can't make a production chat token.
- A browser can't reach production data by changing a request field.
Exception: dashboard and CLI endpoints. There you're logged in as a
developer, not using a key, so you pass ?environment=. It defaults to
development.
What this looks like in practice
Say your backend creates a room called lobby in both development and
production. These calls run on your backend (or in a terminal) with each
environment's key. The same name means two different rooms:
# Development
curl -H "Authorization: Bearer $DEV_KEY" -H "Content-Type: application/json" \
-d '{"name":"lobby"}' "$LIVQENO_API_URL/v1/rooms"
# Production — not a conflict
curl -H "Authorization: Bearer $PROD_KEY" -H "Content-Type: application/json" \
-d '{"name":"lobby"}' "$LIVQENO_API_URL/v1/rooms"A key can't see the other environment, even with the exact id:
curl -H "Authorization: Bearer $DEV_KEY" .../v1/rooms/<the production room id>
# 404 { "code": "RAVEN_ROOM_NOT_FOUND" }You get 404, not 403, on purpose. A 403 would tell an attacker the id exists. The same rule applies to conversations, messages, and RTC tokens.
Webhooks
A webhook endpoint is the URL on your backend where Livqeno sends events. You register each endpoint for one environment, so test events never reach your production server and real customer events never reach a test URL:
POST /v1/projects/{id}/webhooks
{ "url": "https://api.example.com/hooks", "environment": "PRODUCTION" }Every event says which environment it came from:
{
"id": "evt_9f2c41ab77e0",
"type": "message.created",
"projectId": "…",
"environment": "PRODUCTION",
"createdAt": "2026-08-19T09:31:04.221Z",
"data": { }
}Events are matched to the right environment before they are sent. Real customer data never goes to a test URL on someone's laptop.
Moving an existing project to environments
Only relevant if your project existed before environments were added.
Everything created before environments existed is in development: API keys, rooms, conversations, webhook endpoints, and stored telemetry. Nothing changed in how it works.
To start using production:
- Run
livqeno keys create --environment productionfor your production backend. - Register a production webhook endpoint (if you use webhooks).
- Put the new key in your production deployment.
- Revoke the old key once nothing uses it.
Your development traffic keeps working the whole time.
Next steps
- Create a production key, and put it in your production backend's secret storage. See API keys.
- Register a production webhook endpoint, if you use webhooks. See Webhooks.
- Go through the Production checklist before launch.
The idea behind environments: Environment.