> ## 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.

# Releases

> Freeze your app's delivery config, publish it on purpose, roll it out to a percentage of installs and roll it back.

A **release** is an immutable snapshot of the configuration Salesive delivers to your installs:

* the webhook URL, signing secret and `webhookTopics`
* the launch URL (`appUrl`)
* the redirect URIs
* the storefront extensions (embeds and blocks)
* the dashboard extensions
* the MCP server URL
* the workflow actions and triggers your app declares

Versions are per app, start at 1 and are never reused. The snapshot cannot be rewritten after the
release is created.

> [!NOTE]
>
> Development config (`devConfig`) is deliberately not part of a release. It is your own testing
> target, and a development install is never pinned to a release.

## Why use a release

Editing your app's fields changes what every install sees immediately. A release lets you freeze a
working config, publish a change deliberately, send it to a small share of installs first, and go
back to the previous config without editing anything by hand.

## Create and publish

Create a draft from the current config, then publish it:

```bash theme={null}
# 1. Snapshot the current config as a new version
curl -X POST https://api.salesive.com/api/v1/apps/developer/<appId>/releases \
  -H "Authorization: Bearer <your-merchant-session-token>" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "New webhook endpoint" }'

# 2. Publish version 1 to every install
curl -X POST https://api.salesive.com/api/v1/apps/developer/<appId>/releases/1/publish \
  -H "Authorization: Bearer <your-merchant-session-token>" \
  -H "Content-Type: application/json" \
  -d '{ "rolloutPercent": 100 }'
```

Publishing makes the release current, retires the previous release and writes the snapshot back onto
the app, so consumers that do not read releases still serve exactly what you published. Active
production installs are pinned to the release.

## Stage a rollout

Publish below 100 to send the change to a share of installs first:

```bash theme={null}
curl -X POST https://api.salesive.com/api/v1/apps/developer/<appId>/releases/2/publish \
  -H "Authorization: Bearer <your-merchant-session-token>" \
  -H "Content-Type: application/json" \
  -d '{ "rolloutPercent": 25 }'
```

Installs are bucketed deterministically from a hash of the installation id, so 25 percent always
selects the same quarter. Raising it to 50 percent adds the next quarter and leaves the first one
where it is; nobody is reshuffled.

A staged publish needs an earlier published release for the rest of the installs. The first release
of an app cannot go out below 100 percent.

Widen or narrow the **current** release later without creating a version:

```bash theme={null}
curl -X POST https://api.salesive.com/api/v1/apps/developer/<appId>/releases/2/rollout \
  -H "Authorization: Bearer <your-merchant-session-token>" \
  -H "Content-Type: application/json" \
  -d '{ "rolloutPercent": 50 }'
```

`rolloutPercent` is required on this route, because an omitted value would silently do nothing.

## Roll back

```bash theme={null}
curl -X POST https://api.salesive.com/api/v1/apps/developer/<appId>/releases/1/rollback \
  -H "Authorization: Bearer <your-merchant-session-token>" \
  -H "Content-Type: application/json" \
  -d '{ "rolloutPercent": 100 }'
```

A rollback publishes the chosen release's snapshot as a **new version**. The old release keeps its
version and snapshot; nothing is rewritten. You cannot roll back to a draft, because it was never
published, and you cannot roll back to the release that is already current.

## What an install runs

* A new or reactivated production install is pinned to the current release, or to the previous
  published release when its stable bucket falls outside a staged rollout.
* A pinned install uses its release's webhook URL, signing secret and topics, even after you edit
  the app's fields.
* A development install is never pinned and keeps using `devConfig`.
* An install created before releases existed has no release and falls back to the app's current
  fields.

## Keep the response server side

A release response can include the webhook signing secret. The routes are owner only, require your
merchant session and never accept an app token, but do not log the response or ship it to a browser
you do not control.

## Next steps

> [card] [Release endpoints](https://docs.salesive.com/apps-api/releases.md)
>
> Request and response shapes for every release route.

> [card] [Webhooks](https://docs.salesive.com/apps-api/webhooks.md)
>
> How the pinned URL, secret and topics are used on delivery.


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