# Versioning and updates

> Semantic versioning rules for app definitions, what each bump means, changelogs, beta versions, upgrading installed apps, automatic updates, and editing listing details without a new version.

Source: https://developer.kustomer.com/docs/apps/versioning

Every registered version of an app is immutable. To change anything an org installs (components, settings, roles) you register a new version and orgs upgrade to it. Only listing details can change in place.

## Version numbers

`version` is a [semantic version](https://semver.org): `MAJOR.MINOR.PATCH`, with an optional pre-release tag such as `1.5.0-beta`.

| Rule                                          | Error if broken                                                                         |
| --------------------------------------------- | --------------------------------------------------------------------------------------- |
| Each version is registered once               | `409` This version has already been registered. Please increment the version.           |
| A new version must be greater than the latest | `400` Cannot register outdated version. Version must be greater than X.                 |
| Changing `roles` needs a new major version    | `400` Roles do not match that of the previous version, a major version bump is required |

### Choose the bump

| Bump      | Use it for                                                                                                                                  | Example           |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| **Major** | Anything an org must review: changed `roles`, removed components, renamed settings, changed action inputs, or new data sent to your servers | `1.4.2` → `2.0.0` |
| **Minor** | New, backward-compatible components and settings                                                                                            | `1.4.2` → `1.5.0` |
| **Patch** | Fixes that don't change the app's surface: template fixes, copy, KView layout                                                               | `1.4.2` → `1.4.3` |

Major versions are never applied automatically, so admins always get to review them. For marketplace apps, a major version also gets a full review, including privacy. See [Publish to the marketplace](https://developer.kustomer.com/docs/apps/marketplace#updates).

## Changelog

`changelog` maps versions to the release notes Kustomer shows admins on your app's page. Each entry starts with the release month in double braces, followed by Markdown:

```json title="changelog"
{
  "changelog": {
    "1.5.0": "{{October 2026}} Added the **Refund order** workflow action.",
    "1.4.3": "{{September 2026}} Fixed the order timeline in dark mode.",
    "1.4.0": "{{August 2026}} Orders now sync on every update, not just on create."
  }
}
```

Keys are versions, optionally with `-alpha` or `-beta`. Add an entry for each version you register, and say what changed for admins and agents, not how you built it. Marketplace apps must include release notes.

`changelog` is app-wide, so you can fix a typo in an old entry without a new version; see [Edit without a new version](#edit-without-a-new-version).

## Beta versions

Register a pre-release version such as `1.5.0-beta` to try a change in a sandbox org before it's final. Beta versions are never installed automatically: admins install them on purpose. When you're done, register the final version (`1.5.0`), which sorts after its betas.

Marketplace listings can't contain betas. Test with a private app instead.

## Upgrade an installed app

An org upgrades by installing the newer version. Admins do this from the app's page; with the API, call the install endpoint with the target version:

`POST /v1/apps/install`

```json title="Body"
{ "app": "acme_orders", "version": "1.5.0" }
```

Omit `version` to install the latest. Kustomer compares the two versions and changes only what differs:

| Component in the new version | What happens                                         |
| ---------------------------- | ---------------------------------------------------- |
| New                          | Created                                              |
| Changed                      | Updated                                              |
| Removed                      | Deleted, **except Klasses**, which are never deleted |

Klasses stay because deleting one would delete every record of that type. Their KObjects stay with them.

Installs run in the background. Check progress with:

`GET /v1/apps/install-state/{app}-{version}`

`attributes.status` is `installing`, `installed` or `install_failed`, and `attributes.previousVersion` is the version you upgraded from. If an upgrade fails, the org keeps the previous version and you can retry.

| Error                                                   | Meaning                                                                                                  |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `409` already installed                                 | The org already has this version                                                                         |
| `409` currently installing                              | Another install of this version is in progress                                                           |
| `409` Apps cannot be updated while they are deactivated | [Enable](https://developer.kustomer.com/docs/apps/register-and-install#disable-and-enable) the app first |

> **Roll back with a new version:** To undo a bad release, register a new patch version with the previous behavior and upgrade to it. That keeps every org's version history moving forward.

## Automatic updates

Admins can let an installed app update itself when you register a new version. The flag is per org, on the installed app:

`PATCH /v1/apps/{app}`

```json title="Body"
{ "autoUpdate": true }
```

A new version is skipped, and left for the admin to install, when:

- It's a **major** version.
- It's a **pre-release**, such as `1.5.0-beta`.
- The app is disabled in the org.
- An install is already in progress.
- An app it depends on isn't installed, or the installed version isn't one it supports.

Treat automatic updates as a convenience for orgs, not a delivery guarantee: always assume some orgs are on older versions, and keep your hooks and APIs compatible with every version you still support.

## Edit without a new version

Listing details that don't install anything can change in place. Two endpoints cover them:

**One version**

`PATCH /v1/apps/available/{app}-{version}`

Changes the listing of a single version: `title`, `iconUrl`, `description`, `screenshots`, `instructions`, `releaseNotesUrl`, `postInstallMessage` and `auth`.

```bash title="cURL"
curl -X PATCH "https://acme.api.kustomerapp.com/v1/apps/available/acme_orders_${ORG_ID}-1.5.0" \
  -H "Authorization: Bearer $KUSTOMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description": "Sync Acme orders and issue refunds from Kustomer."}'
```

**Every version**

`PUT /v1/apps/available/{app}-{version}`

Changes app-wide fields for all versions: `appDetails`, `redirectUris`, `tags`, `changelog` and `auth`.

```bash title="cURL"
curl -X PUT "https://acme.api.kustomerapp.com/v1/apps/available/acme_orders_${ORG_ID}-1.5.0" \
  -H "Authorization: Bearer $KUSTOMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"changelog": {"1.5.0": "{{October 2026}} Added the **Refund order** workflow action."}}'
```

Use these to rotate a third-party OAuth client secret in `auth`, or to add a redirect URI, without making every org upgrade.

## Version history at a glance

```mermaid
gitGraph
  commit id: "1.0.0"
  commit id: "1.1.0 new KView"
  branch beta
  commit id: "1.2.0-beta"
  checkout main
  merge beta id: "1.2.0"
  commit id: "1.2.1 fix"
  commit id: "2.0.0 new roles" type: HIGHLIGHT
```

Orgs on automatic updates move from `1.0.0` to `1.2.1` without anyone acting. They stop at `2.0.0` until an admin approves the new roles.
