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

# Release endpoints

> Create an immutable snapshot of your app's delivery config, publish it to all or a share of installs, widen the rollout and roll back.

## Authentication

These routes are for the **app owner's merchant session**, never an `app_` token:

```http theme={null}
Authorization: Bearer <merchant-session-token>
```

Every route checks that the app belongs to the signed-in developer. Responses can include the
webhook signing secret, so keep them server side.

## The release object

```json theme={null}
{
  "_id": "66b1f0a3c2d4e5f6a7b8c9d0",
  "app": "66b1f0a3c2d4e5f6a7b8c9aa",
  "version": 2,
  "status": "published",
  "snapshot": {
    "webhookUrl": "https://yourapp.com/webhooks/salesive",
    "webhookSecret": "whsec_...",
    "webhookTopics": ["orders/created", "orders/fulfilled"],
    "appUrl": "https://yourapp.com/app",
    "redirectUris": ["https://yourapp.com/oauth/callback"],
    "mcpServerUrl": null,
    "extensions": { "embeds": [], "blocks": [] },
    "dashboardExtensions": [],
    "workflow": null
  },
  "createdBy": "66b1f0a3c2d4e5f6a7b8c9bb",
  "publishedAt": "2026-11-07T09:00:00.000Z",
  "rolloutPercent": 100,
  "notes": "New webhook endpoint",
  "createdAt": "2026-11-07T08:55:00.000Z",
  "updatedAt": "2026-11-07T09:00:00.000Z",
  "installs": 128
}
```

| Field | Meaning |
| - | - |
| `version` | Per app, starts at 1, never reused. Immutable. |
| `status` | `draft`, `published` or `retired`. |
| `snapshot` | The frozen delivery config. Immutable after creation. |
| `rolloutPercent` | The share of installs this release is published to. |
| `installs` | Added by the list route: active installs pinned to this release. |

## List releases

```http theme={null}
GET /api/v1/apps/developer/:id/releases
```

```json theme={null}
{
  "status": 200,
  "success": true,
  "message": "Releases retrieved",
  "data": {
    "releases": [],
    "currentRelease": "66b1f0a3c2d4e5f6a7b8c9d0",
    "rolloutPercent": 100
  }
}
```

Newest version first. `currentRelease` is the published release installs are being pinned to, or
`null` when the app has never published one.

## Create a draft

```http theme={null}
POST /api/v1/apps/developer/:id/releases
Content-Type: application/json

{ "notes": "New webhook endpoint" }
```

Snapshots the app's **current** delivery config into a new draft version. `notes` is optional, up to
2000 characters. Returns `201` with the release object.

A release freezes `webhookUrl`, `webhookSecret`, `webhookTopics`, `appUrl`, `redirectUris`,
`extensions`, `dashboardExtensions`, `mcpServerUrl` and `workflow`. Development config (`devConfig`)
is not part of a release.

## Publish a release

```http theme={null}
POST /api/v1/apps/developer/:id/releases/:version/publish
Content-Type: application/json

{ "rolloutPercent": 100 }
```

`rolloutPercent` is a whole number from 0 to 100 and defaults to 100. Publishing makes the release
current, retires the previous release, writes the snapshot back onto the app and pins active
production installs.

```json theme={null}
{
  "status": 200,
  "success": true,
  "message": "Release published",
  "data": {
    "release": {},
    "previousRelease": "66b1f0a3c2d4e5f6a7b8c9c0",
    "assignment": {
      "total": 128,
      "assignedCurrent": 32,
      "assignedPrevious": 96,
      "unchanged": 0
    }
  }
}
```

A publish below 100 needs an earlier published release for the rest of the installs. Assignment is
deterministic: the same installation id always falls in the same bucket, so raising the percentage
later adds installs and never reshuffles them.

## Roll back

```http theme={null}
POST /api/v1/apps/developer/:id/releases/:version/rollback
Content-Type: application/json

{ "rolloutPercent": 100 }
```

Publishes the chosen release's snapshot as a **new version**. The old release keeps its version and
snapshot; nothing is rewritten. The response is the publish response plus `rolledBackFrom`, the
release you rolled back to.

You cannot roll back to a draft, because it was never published, or to the release that is already
current.

## Change the rollout

```http theme={null}
POST /api/v1/apps/developer/:id/releases/:version/rollout
Content-Type: application/json

{ "rolloutPercent": 50 }
```

Widen or narrow the **current** release without creating a version. `rolloutPercent` is required
here, because an omitted value would silently do nothing. Returns the release and the assignment
counts. This is the route to move the rest of the installs later.

## Errors

| Status | Meaning |
| - | - |
| `400` | `rolloutPercent` is not a whole number from 0 to 100. |
| `400` | A staged publish has no earlier release for the rest of the installs. Publish the first release at 100 percent. |
| `400` | A draft was chosen for rollback; it was never published. |
| `400` | The only published release cannot go below 100 percent. |
| `404` | The app is not yours, or the version does not exist. |
| `409` | The release is already published, or it was retired (use rollback). |
| `409` | The chosen release is already current. |
| `409` | Only the current release can change its rollout. |

## Next steps

> [card] [Releases guide](https://docs.salesive.com/apps/releases.md)
>
> When to create, publish and roll back.

> [card] [Webhooks](https://docs.salesive.com/apps-api/webhooks.md)
>
> How a pinned release is used on delivery.


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