> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revring.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Versions and Publishing

> Every change to an agent is recorded, restorable, and attributable. Choose whether saves go live at once or wait for you to publish.

## Version history

Every write to an agent creates a version automatically. There is no "save a version" step to remember: a prompt edit, a custom tool change, a phone number added or removed, a restore, all of them land in the history with:

* **Who** made the change (the dashboard user's email, or the API key name)
* **What** changed (the list of fields, with before/after values on the version detail)
* **When**
* A full snapshot of the configuration at that point

The history survives agent deletion, so a deleted agent's final configuration is still readable.

See the [List Agent Versions](/api-reference/agents/list-revisions) and [Get Agent Version](/api-reference/agents/get-revision) references. In the dashboard, open the agent and use the **History** tab.

## Restoring a version

Restoring applies a version's configuration back onto the agent through the same validation as a normal save, and records the restore as its own version, so the state you had before stays in the history.

Restore never changes phone numbers or knowledge base links (live routing and knowledge lifecycle are kept as they are), and references to a trunk, messaging connection or folder that no longer exist are skipped and reported.

See [Restore Agent Version](/api-reference/agents/restore-revision).

## Publishing

By default **every save goes live**: the next call uses whatever is saved. That is the right default for a single builder iterating quickly.

When several people work on the same agent, or you want to prepare a change and release it deliberately, switch the agent to **manual publishing**. The agent then has two states:

| State | What it is | Who sees it |
| - | - | - |
| Draft | The configuration as saved in the dashboard or by `PATCH /agents/{id}` | Editors, chat and voice tests |
| Published | The version conversations run on | Callers and texters: outbound calls, inbound numbers, the web widget (calls and chat), SMS replies |

While you edit, calls keep using the published version. When the draft is ready, **Publish** makes it live for new calls (calls already in progress are not changed).

### Switching modes

```json theme={null}
PATCH /v1/agents/{id}
{ "publishMode": "manual" }
```

Switching to manual publishes the current draft at once, so the agent never silently runs an older state. Switching back to `auto` clears the published version and every save is live again.

The agent carries three fields for this:

* `publishMode`: `auto` or `manual`
* `publishedRevision`: the version calls run on (manual mode); `null` when nothing is published yet, in which case the draft runs
* `hasUnpublishedChanges`: manual mode only, `true` when the draft differs from the published version (on `GET /agents/{id}`; the dashboard shows it as a badge next to the Publish button)

### Publishing

```json theme={null}
POST /v1/agents/{id}/publish
{}
```

Publishes the current draft. The response carries the version calls now run on. Publishing is recorded in the history as a `published` version with the actor, so "who put this live?" is always answerable. Publishing a draft that is already live is a no-op.

To make an earlier version live without touching the draft:

```json theme={null}
POST /v1/agents/{id}/publish
{ "revision": 12 }
```

This is the fastest rollback: the draft keeps your in-progress work, and calls go back to version 12 immediately.

See [Publish Agent](/api-reference/agents/publish).

### Testing before you publish

Chat tests, voice tests and the dashboard test panel run the **draft** by default. That is the point of manual publishing: test the change, then publish it. To check what callers get today, start a run with `"environment": "production"` (or an environment name) on `POST /test-suites/{id}/runs`. Real calls, inbound numbers, the web widget and SMS replies use the published version (prompt, SMS and web-chat prompts, variables, custom tools, voice and conversation settings).

### Which version a call ran on

Every call record and post-call webhook carries `agentRevision`, the version the call ran on (`null` for agents in auto mode). When a caller reports "the agent said X", that number tells you exactly which configuration was live, and the version detail shows the prompt it ran with.

<Note>
  Phone numbers, the SIP trunk, knowledge base links and the agent's active/disabled status are infrastructure, not configuration: they are always live, whatever version is published. Adding a number to an agent in manual mode takes effect at once.
</Note>

## Environments

Environments let one agent serve more than one audience without duplicating it: for example `staging` pinned to a newer version with its own variable defaults, while `production` stays on the published version.

* `production` always exists. It is the published version and changes through publishing.
* A named environment pins a **version** (or the saved draft, with `revision: null`) and carries **variable defaults** that override the agent's on calls in that environment. Up to 10 per agent.
* Names are lowercase slugs and cannot be renamed.

```json theme={null}
PUT /v1/agents/{id}/environments/staging
{ "revision": 14, "variables": { "tone": "formal", "region": "EU" } }
```

### What runs in an environment

| Entry point | How to choose the environment |
| - | - |
| Outbound call | `environment` on `POST /calls` (omit for production) |
| Inbound number | `environment` on the number (`POST /agents/{id}/phone-numbers` or `PATCH /agents/{id}/phone-numbers/{phoneId}`) |
| Web widget (calls and chat) | `environment` in the agent's widget config |
| SMS replies | Production |
| Chat, text and voice tests | The draft by default; `environment` on the run (`production` or a name) to test a live version |

Unknown names are refused on `POST /calls` with `environment_not_found` before anything is dialed. A number or widget bound to an environment that was later deleted falls back to production rather than failing the caller. Deleting an environment is refused while numbers are still bound to it.

Every call record and post-call webhook carries `environment` (`null` for production) next to `agentRevision`.

See [List Agent Environments](/api-reference/agents/list-environments), [Create or Update Environment](/api-reference/agents/upsert-environment) and [Delete Environment](/api-reference/agents/delete-environment).

<Tip>
  A common setup: keep `production` on manual publishing, point `staging` at the draft (`revision: null`) and bind a spare inbound number to `staging`. Call that number to hear the draft on a real phone; publish when it sounds right.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.