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

# Promote and go live

> Land a release on a new Xano branch of your workspace with xanosdk promote, guard the switch with --expect-live, handle shared-schema and constraint refusals, and publish the frontend that belongs to the release.

`xanosdk promote` lands a release on your workspace. It always lands on a **new Xano branch**,
and the live Xano branch keeps serving until you switch. Going live is a separate, deliberate
step.

## Promote a release

```bash theme={null}
npx xanosdk promote v1.4.0 --branch v1.4.0
```

```
  on your-instance.xano.io · workspace 3
! This lands a release the server holds, so the local pre-flight did not run:
  no plan preview, no prune scope — its table changes are checked against the destination below
  and the release's workspace settings (preferences, request history, realtime, workspace middleware) apply to the whole workspace — they are shared by every branch; its name and description are kept
  what it has instead: a named release that came up and answered, and can be re-landed
! The promote will add to the tables every branch shares — live included, as soon as it lands:
  create table notes
? Land release "v1.4.0" in your workspace on branch "v1.4.0", applying its table change to the live workspace too? (y/N) y
→ Landing v1.4.0 in your workspace on branch "v1.4.0"
→ Resolving branch "v1.4.0"
→ Reading workspace 3 on branch "v1.4.0"
i Recorded what this project landed on your-instance.xano.io/workspace/3 in xano/xano.lock — commit it: `--prune` deletes only what this record names.
i Recorded the sync baseline for branch "v1.4.0" in xano/xano.lock. Commit it: `workspace diff` reads it to say which side changed.
✓ Landed v1.4.0
  on branch v1.4.0, not live yet — serve it with `npx xanosdk workspace branch set-live v1.4.0 --yes` (a promote with `--set-live` lands and serves in one run)
  Verified: all 7 declared object(s) arrived.
  See what landed with `npx xanosdk workspace export --branch v1.4.0`.
```

`--branch` names the new Xano branch. Without it, the label is derived from the release and the
moment, such as `v1.4.0-20261013T140000Z-3f2a`, and the run prints it. A label that already
exists is refused before anything lands. On a terminal, promote asks before it writes; in CI,
pass `--yes`.

After landing, promote reads the Xano branch back and checks that every declared object arrived.
Look around before you serve it: list the Xano branches, and open the new one in the Xano editor
from your Xano dashboard.

```bash theme={null}
npx xanosdk workspace branch list                  # every Xano branch, and which one is live
npx xanosdk workspace diff ./xano/index.ts --branch v1.4.0   # compare the new Xano branch with your project
```

## Go live

Switch live to the new Xano branch, and say which branch you expect to be live now:

```bash theme={null}
npx xanosdk workspace branch set-live v1.4.0 --expect-live v1.3.2
```

Or land and serve in one run:

```bash theme={null}
npx xanosdk promote v1.4.0 --branch v1.4.0 --set-live --expect-live v1.3.2
```

`--expect-live` refuses unless `v1.3.2` is the live Xano branch. Promote checks it before
landing and again immediately before switching. If live moved in between, the new Xano branch
stays landed but is not served. The platform has no compare-and-set, so the guard narrows the
race between two releases going live at once; it does not close it. A check that fails exits
`2` with `SDK_LIVE_BRANCH_MISMATCH`, and `details.conflictsWith.live` names the Xano branch that is
live.

`--set-live` is applied only to a landing that verified. If the read-back finds an object that
did not arrive, or a public URL slug pinned in code served under another value, the run fails
(`verify: no`, exit `2`), nothing is made live, and the Xano branch stays as evidence. Remove it
with `xanosdk workspace branch delete <label>` once you have looked.

## What promote refuses

Promote checks the release against your workspace before it lands anything. Each refusal exits
`2`, and `--yes` does not waive it.

| Code | Why | What to do |
| - | - | - |
| `SDK_SHARED_SCHEMA_CHANGE` | The release alters a table. Tables are shared by every Xano branch, so the change reaches live as the release lands, before any `--set-live`, and deleting the branch does not undo it. | Pass `--allow-shared-schema-changes` once you accept that, or cut a release without the change. |
| `SDK_IDENTITY_CONFLICT` | The workspace already uses a name in the release for a different object, or a slug the release pins is served by another workspace. | A release's identities are fixed when it is cut, so fix the project, then cut and promote a new release. |
| `SDK_CONSTRAINT_VIOLATION` | The workspace's rows break a unique index the release adds. | Nothing landed and no Xano branch was made. Remove the duplicate rows or the index, then promote again. |

New tables and new columns are additions: they are named and they land without the flag. A
non-unique index added or dropped passes too. A **unique** index added stays refused.

A column dropped beside a column added is not a rename: columns have no rename identity, so the
old values are destroyed and the new column starts empty. To keep them, add the new column in
one release, backfill it, and drop the old one in the next. [Schema
changes](/govern/schema-changes) walks through it.

## What promote does not do

* **No preview and no prune.** The platform lands the release itself, so promote runs no local
  plan and deletes nothing. An object your project removed stays on the workspace. When you
  need a preview or a deletion, use the [merge path](/ship/merge-path).
* **No env overwrite.** Env is add only: a name the workspace already holds keeps its value. See
  [Env and secrets](/build/env-and-secrets).
* **No guard against edits in the Xano editor.** The 1.0.8 drift guard covers
  `deploy --to workspace` only. See [Drift](/govern/drift).

## Publish the frontend that belongs to the release

A frontend is published separately from the backend. Publish it once the release is live, and
check that it lands in front of the backend it was built for:

```bash theme={null}
npm run build
npx xanosdk publish ./frontend/dist --to workspace --release v1.4.0 --branch v1.4.0
```

`--release` checks that the release exists and reports it with the publish. `--branch` refuses
unless that Xano branch is the live one. Publishing to your workspace asks before it replaces
what users see; pass `--yes` in CI. A promote leaves the static host alone, so the frontend
that was serving keeps serving until you publish.

## If the outcome is unknown

Exit `9` means promote sent the landing and the answer was lost. Do not run it again blind,
since a bare re-run lands a second Xano branch. Read first:

```bash theme={null}
npx xanosdk workspace branch list --json
```

If the label is there, the release landed. If it is absent once the time in `resolveNotBefore`
has passed, nothing landed: re-run with the same `--branch` and `--yes`. An "absent" read before
then is not proof, because the server may still be finishing the write. The run's `--json` document carries the exact steps under
`resolveSteps`. See [Exit codes and outcomes](/help/exit-codes-and-outcomes).

## Going back

Going back is switching live to the Xano branch that served before:
`npx xanosdk workspace branch set-live v1.3.2`. It restores logic only. A table change the
release made stays made. [Rollback and recovery](/govern/rollback-and-recovery) covers it.

## Next

[Tenants](/ship/tenants): land the same release on a tenant.


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