# Environments

RelationsAI has two modes, test and live, selected by the key you send rather than by a different URL. This page explains what each mode does, how data is kept apart and how to tell which mode an object belongs to.

## One base URL, two modes

All requests go to `https://voice-api.relationsai.com/v1`. A `rai_test_` key operates in test mode and a `rai_live_` key in live mode; there is no header, parameter or separate host to choose a mode.

| Property | Test mode | Live mode |
| --- | --- | --- |
| Key | `rai_test_...` | `rai_live_...` |
| `livemode` | `false` | `true` |
| Calls | Simulated; the number picks the result | Real calls |
| Charges | Never; no balance or spend limit checks | Per started minute of talk time |
| Daily API call limit | None | Applies |
| Compliance checks | Enforced, on test-mode data | Enforced |
| Webhooks | To test-mode endpoints | To live endpoints |
| Rate limits | Counted separately | Counted separately |
| Sample agent and number | Available | Not available |

The compliance checks are the do-not-call list, consent, calling hours and the per-number daily limit. The daily API call limit is described in [Rate limits](/fundamentals/rate-limits#daily-call-limit); in test mode `limits.daily_call_limit` is `null`.

## The livemode field

Every object, list item and event includes `"livemode": true` or `false`, so you can always tell which mode produced it. Check it where it matters: a production worker can refuse to act on an event or an object with `"livemode": false`, and a test suite can assert that everything it touched was `false`.

## Data separation

**Activity data is per mode.** Calls, campaigns and their recipients, contacts, do-not-call entries, webhook endpoints, events and webhook deliveries created in one mode exist only in that mode. A test key never sees live calls or contacts and cannot change them, and a live key never sees test data. An id from the other mode answers [`resource_not_found`](/errors/resource_not_found), exactly as an id that does not exist. Test-mode activity does not appear in the console's normal screens.

This also means each mode has its **own** contacts, consent records and do-not-call list. A number on your live do-not-call list is not on your test list unless you add it there too.

## Shared configuration

Agents and phone numbers are configured in the console and are visible, read-only, in both modes, so you test with the same agents you will use live. (`livemode` on an agent or a number tells you which key read it.)

Test mode also adds a built-in **Sample agent** (`agent_1ZltiWzxrXmMprGD6q63`, always published and ready) and a sample caller number `+12025550150` (`pn_6Vhm3sFrB5UpmXAnsvmDu`), so a new workspace can start before it has agents or numbers of its own. A live key cannot see or use them.

One difference for your own agents: in test mode an agent must be switched on and saved for calling in the console, but it does not need to be published or to have a phone number. In live mode it needs both. Check with [`GET /agents/{agent_id}/readiness`](/api/agents#check-whether-an-agent-can-place-calls) using the key you will use.

## Using environments in your code

- Read the key from configuration (for example an environment variable or a secret manager) and never branch on its value in business logic. Switching from test to live should be a configuration change, not a code change.
- Give each environment its own key: test keys for local development, CI and staging; a live key only in production.
- Give each environment its own webhook endpoint, and register test endpoints with a test key and live endpoints with a live key.
- Store ids together with the mode they came from. A test-mode `call_...` id is meaningless to a live key.
- At startup, call [`GET /workspace`](/api/workspace#retrieve-the-workspace) and check `livemode` against what the environment expects, so a misconfigured deploy fails loudly instead of placing real calls from staging (or simulated ones from production).

When you are ready to switch, follow [Going live](/guides/going-live).
