# Test and live (/docs/concepts/environments)



Every project has two environments, **test** and **live**. Test is your rehearsal space: build a quiz, try it with pretend members, and change your mind as often as you like. Live is what your real members use.

Each environment keeps its own members, progress, points, rewards, settings and history, so nothing you try in test touches a real member.

In live, Console marks every project page with a mint strip along the top of the header and a **Live** badge beside the page title, and confirmations for actions that affect members name the environment they apply to.

## What you can change in live [#what-you-can-change-in-live]

Changes come in two kinds:

* **What your program is**, such as a quest, its reward, a badge, or a leaderboard. You change these in test, and a person on your team moves them to live with a [promotion](/docs/concepts/promotion).
* **Running the program day to day**, such as pausing a quest, reviewing submissions, correcting a member's points, or managing a group. You do these directly in live.

| Kind                 | Examples                                                                                                                                                                                                                                           | In live                                                                                                                                                                                       |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Definitions          | Quests, their settings values and archive state; Quest Studio drafts; point ledgers; badges; the project calendar; profile settings; pickup policy; stock items; a leaderboard's exclusion-group binding; archiving or restoring any resource      | Refused for every credential, Console included. Make the change in test, then [promote](/docs/concepts/promotion) it.                                                                         |
| Operations           | Pausing and resuming quests, redemptions, offers and trackers; point changes; attempt review; settlement approval; member and profile moderation; reward corrections; stock corrections; groups and their members; badge awards; referral controls | Accepted under the caller's permissions.                                                                                                                                                      |
| Promotions           | `domino promote`, `management.promotions.prepare`                                                                                                                                                                                                  | Prepared from test with every definition. A person approves each one in Console. See [promotion](/docs/concepts/promotion).                                                                   |
| Code deployments     | `domino deploy --environment live`, `management.deployments.preview`                                                                                                                                                                               | Refused for every credential, Console included. Deploy to test, then promote. See [Publish behavior to live](/docs/build/publishing#publish-behavior-to-live).                                |
| Environment settings | Integrations, webhooks, member sign-in, hosted-app secrets                                                                                                                                                                                         | Set in each environment on its own. A promotion never copies them; it warns when live lacks one test uses.                                                                                    |
| Plugin connections   | **Integrations**, `domino connections`, `management.connections`                                                                                                                                                                                   | Connected in each environment on its own, with its own secrets or access granted at the service. A promotion never copies one and doesn't warn when live lacks one, so connect live yourself. |

Looking things up and previewing changes work in live too, because they change nothing.

* **Definitions reach live through a promotion.** A [promotion](/docs/concepts/promotion) carries every definition in test, from code and from Console alike, to live when a person approves it. Resources match by authoring key.
* **Code reaches live through a promotion too.** Live refuses code sent to it directly, so your developer always publishes to test first.
* **App login keys belong to one environment.** A hosted app's staging and preview addresses sign members in to test and its live address to live, so a [key for one of those addresses](/docs/build/app-login#pick-the-environment-for-the-address) is created only in the environment that address serves. A key for your own app's local address, such as `http://localhost:3000`, is a Test key only: [develop on localhost](/docs/build/app-login#develop-against-domino-on-localhost) against Test, and give the live app an HTTPS address. A promotion never copies keys.

> [!DEV]
> A personal API key works only in the environment it was issued for. Reads and previews work in live, except a code deployment preview, which starts a direct live deployment that live refuses.
>
> In live, a `domino login` CLI session makes only a few changes, such as promoting from test and setting app secrets, and an MCP connector or automation key makes none; their other live writes get 403 `console-approval-required`. [What each credential may do in live](/docs/concepts/access#what-each-credential-may-do-in-live) lists them. For other live operations, create a live API key in Console (**Settings → API keys**).

## When live refuses a change [#when-live-refuses-a-change]

In live, Console shows editors for definitions as read-only, with the note "Live changes only through a promotion from test." Choose **Edit in Test** to open the same page in test, and **Promote to live** when you're ready. Day-to-day controls stay available.

Trying the same change again in live never works. Make it in test, then [promote](/docs/concepts/promotion) test to live.

> [!DEV] Errors
> The permission check comes first: a caller without the permission gets 403 `permission-required`. A caller with it gets HTTP 422, shown below. A code deployment sent to live gets the same code, with the message "Code changes in test and reaches live through a promotion. Deploy to test, then run `domino promote`."
>
> | Where | What you see |
> | --- | --- |
> | Console | **Promote to live** prepares a promotion for people with publish permission. |
> | CLI | Error code `ENVIRONMENT_UNSUPPORTED` (exit 1) with `apiCode: "promotion-required"` and `status: 422`. `domino quests archive` and `unarchive`, and the deprecated `domino resources archive` and `unarchive`, stop before sending and ask for `--environment test`. |
> | Management client | `ManagementError` with `status: 422` and `code: "promotion-required"`. |

```json
{
  "error": "Definitions change in test and reach live through a promotion. Make this change in the test environment.",
  "code": "promotion-required"
}
```
