# Releases and rollbacks

> List every release of a project, see what each one was built from, and put an earlier release back live without rebuilding it.

Source: https://docs.fortly.com/deploy/releases

Every deploy creates a release with an id like `dpl_…`. Exactly one release per project is live at a time. Building a release and making it live are separate steps, which is what makes a rollback cheap: putting an earlier release back moves your project's traffic to output that was already built and stored. Nothing is rebuilt.

## Release states

| State | Meaning | Can be made live? |
| --- | --- | --- |
| `building` | Its dependencies are being installed and built. | No |
| `ready` | Built and stored, about to go live. | Yes |
| `live` | Serving your project's traffic. | It already is |
| `superseded` | Was live; a later release or a rollback replaced it. | Yes |
| `failed` | Never went live. The `failure` field says why. | No |
| `gone` | Its files are no longer available. | No |

## List releases

**Console**

Open your project and go to **Deployments**. The history lists each release with its state, its short id, its size and when it was made. Select a row to see its details underneath.

**API**

```bash
curl https://api.fortly.com/projects/my-app-ada/deploys \
  -H "Authorization: Bearer $FORTLY_TOKEN"
```

The reply is `{"deploys": [...]}` with the 50 most recent releases, newest first. To list releases across every project you can reach, use `GET /deploys`.

**Agent**

An agent connected over [MCP](https://docs.fortly.com/agents/mcp) with the `deployments:read` scope can call the `list_deployments` tool with a project name. It returns each release's id, creation time, state, source, commit and branch. Agents can read releases; they cannot deploy or roll back.

The fields worth knowing on each release:

| Field | What it holds |
| --- | --- |
| `id` | The release id, `dpl_…`. This is what you roll back to. |
| `state` | One of the states above. |
| `created_at`, `activated_at` | When it was made, and when it last became live. Seconds since the epoch. |
| `source` | `upload` or `github`. |
| `repo`, `branch`, `sha` | For a GitHub release, the commit it was built from. |
| `build` | What ran before it went live, such as `npm ci && npm run build`. Null when nothing ran. |
| `framework` | The framework detected when it was built. |
| `runtime_type` | `static` for files served from storage, `fortly` for a Worker. |
| `failure` | For a failed release, why. |
| `files`, `bytes` | How much the archive unpacked to. |

## Roll back to an earlier release

**Console**

On the project's **Deployments** page, the newest release that can be restored has a **Roll back** button on its row. For any other release, open the row's menu and choose **Roll back to this release**. Every plan can roll back.

**API**

```bash
curl -X POST https://api.fortly.com/projects/my-app-ada/deploys/dpl_abc1234/activate \
  -H "Authorization: Bearer $FORTLY_TOKEN"
```

The reply is `{"deploy": {...}}`, the release now live. See [Deploys API](https://docs.fortly.com/api/deploys) for the full reference.

The switch is a single step: the release that was live becomes `superseded`, the one you chose becomes `live`, and your project's cached responses are cleared so the next request sees it. The log records `Rolled back to version dpl_abc` with the first seven characters of the id.

A rollback can be refused:

| Status | Message | Why |
| --- | --- | --- |
| `404` | `no such release` | No release with that id among the project's 200 most recent. |
| `410` | `that version cannot be made live` | The release is `building`, `failed` or `gone`. |
| `410` | `that release has been cleaned up and cannot be restored` | An older release whose files were kept on the server and have since been removed. |

## What a rollback changes

A rollback changes which code serves your project, and nothing else.

| | After a rollback |
| --- | --- |
| Code serving requests | The release you chose, exactly as it was built |
| Build | None. The stored output is served again. |
| Database | **Unchanged.** Rows and schema changes made since that release stay. |
| Uploaded files | Unchanged |
| Environment values | Unchanged. The release reads the values as they are now, for the names that existed when it was built. |
| Domains and schedules | Unchanged |
| Cached responses | Cleared |

> **Warning:**
>
> The database is not rolled back. If the release you are leaving ran a migration, the release you return to sees the migrated schema. Make schema changes that older code can live with — add columns before you use them, drop them only once no release reads them — or restore data separately from a [backup](https://docs.fortly.com/data/backups).

Static assets belong to the release that shipped them: rolling back serves that release's own files, not whatever a newer release left behind.

## Related

- [Deploying your code](https://docs.fortly.com/deploy): How a release is made, from an upload, the API or a GitHub branch.
- [How builds work](https://docs.fortly.com/deploy/builds): What the build field records, and why a release failed.
- [Backups](https://docs.fortly.com/data/backups): Restore your database, which a rollback does not touch.
- [Deploys API](https://docs.fortly.com/api/deploys): The list and activate routes, with every response.
