# How to Version Your OpenAI Plugin and Handle Updates

> Learn how to version your OpenAI plugin using semantic versioning in app.json. Seamlessly handle updates and breaking changes for robust compatibility with the opencode CLI.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-06-23

---

**OpenAI plugins use a `version` field in the [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest file that follows semantic versioning (MAJOR.MINOR.PATCH), allowing you to manage breaking changes, maintain compatibility, and publish updates via the `opencode` CLI while tracking execution versions through [`run_manifest.json`](https://github.com/openai/plugins/blob/main/run_manifest.json).**

Managing versions is essential for maintaining stable integrations. In the `openai/plugins` repository, every plugin defines its contract through a manifest file located at [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) in the plugin directory. This guide explains how to version your plugin and handle updates using semantic versioning principles and the OpenAI publishing toolchain.

## Understanding the Plugin Manifest Structure

### The version Field in .app.json

Every plugin contains a [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest file that serves as the authoritative source of truth for versioning. For example, in [`plugins/zoom/.app.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.app.json), the `version` field declares the current release:

```json
{
  "name": "Zoom SDK",
  "description": "Interact with Zoom meetings via the Zoom App SDK",
  "version": "0.16.0",
  "manifest_version": "v1",
  "api": {
    "openapi": "openapi.yaml"
  },
  "auth": {
    "type": "oauth",
    "authorization_url": "https://zoom.us/oauth/authorize"
  }
}

```

The `version` field must follow semantic versioning format. When you publish, the `opencode` CLI reads this field to identify the release.

### Semantic Versioning Rules

OpenAI plugins follow strict semantic versioning to communicate compatibility guarantees:

- **MAJOR**: Increment when introducing breaking API or schema changes, such as removing endpoints or changing required authentication flows.
- **MINOR**: Increment when adding backwards-compatible features, such as new optional fields or additional routes.
- **PATCH**: Increment for bug fixes, documentation updates, or internal changes that do not affect the external contract.

## How to Version Your Plugin

### Updating the Manifest Version

When releasing changes, modify the `version` field in your plugin's [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) file according to the nature of your changes. For example, bumping from `0.16.0` to `0.17.0` indicates new features, while `0.16.0` to `0.16.1` indicates a patch.

Always synchronize this update with changes to your [`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml) file referenced in the `api.openapi` field. The OpenAPI specification must accurately reflect the capabilities and schema of the version declared in the manifest.

### Syncing with the OpenAPI Specification

The `api` field in [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) points to your OpenAPI specification (typically [`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml)). Keep these files in lockstep:

1. Update the OpenAPI spec to reflect new endpoints or schema changes.
2. Bump the version in [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) using semantic versioning rules.
3. Ensure breaking changes in the OpenAPI spec correspond to a MAJOR version bump.

## Handling Plugin Updates

### The Update Workflow

Follow this systematic approach when releasing updates to your plugin:

1. **Bump the version** in `plugins/<your-plugin>/.app.json`.
2. **Update the OpenAPI spec** ([`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml)) to reflect any new or changed endpoints.
3. **Add migration notes** in [`README.md`](https://github.com/openai/plugins/blob/main/README.md) or a dedicated [`MIGRATION.md`](https://github.com/openai/plugins/blob/main/MIGRATION.md) describing what changed and how callers should adapt.
4. **Run the plugin test suite** against the new version to catch breaking changes early.
5. **Publish** the new version using the `opencode` CLI.
6. **Monitor** usage metrics and error logs; release a hot-fix (PATCH) quickly if needed.

### Managing Breaking Changes

When you must introduce breaking changes, implement these strategies to minimize disruption:

- **Maintain legacy versions**: Keep the old version alive for at least one release cycle to prevent immediate failures for existing users.
- **Provide deprecation windows**: Announce deprecation at least 30 days before removing functionality, giving consumers time to migrate.
- **Use feature flags**: Implement runtime flags or fallback routes that allow existing clients to continue operating while they update their integrations.

### Version-Drift Detection

The repository includes support for [`run_manifest.json`](https://github.com/openai/plugins/blob/main/run_manifest.json), which records the exact plugin version used for each execution. This enables you to audit which version produced a particular result and trigger re-runs if you upgrade. As documented in the **NGS-Analysis** plugin's README at line 292, the manifest captures the `plugin version` used during execution, allowing you to track version drift across your deployments.

## Publishing New Versions

### Using the opencode CLI

The root-level [`opencode.json`](https://github.com/openai/plugins/blob/main/opencode.json) configures the publishing toolchain. Deploy new versions using the CLI from your plugin root directory:

```bash
opencode publish --manifest plugins/zoom/.app.json

```

The CLI reads the `version` field from the specified manifest and pushes the new bundle to the OpenAI Plugin Registry. Ensure your [`opencode.json`](https://github.com/openai/plugins/blob/main/opencode.json) is properly configured at the repository root to authenticate with the registry.

### Implementing Version-Aware Routing

For plugins supporting multiple versions simultaneously, implement version checking in your middleware. This Node.js example routes requests based on the `x-plugin-version` header:

```javascript
// version check middleware (Express)
app.use((req, res, next) => {
  const requested = req.headers['x-plugin-version'] || '0.0.0';
  if (semver.lt(requested, '0.16.0')) {
    // Old version – route to legacy handler
    return legacyRouter(req, res, next);
  }
  next(); // New version – normal handler
});

```

### Documenting Migrations

Create clear migration guides in your plugin's documentation. Use this structure in your [`README.md`](https://github.com/openai/plugins/blob/main/README.md) or [`MIGRATION.md`](https://github.com/openai/plugins/blob/main/MIGRATION.md):

```markdown

# Migration Guide – 0.16.0 → 0.17.0

## What's new

- Added `participants.list` endpoint (minor bump).
- Removed `clientVersion` field from `config` (major bump).

## Migration steps

1. Update your client to request version `0.17.0` or later.
2. If you still need the old `clientVersion`, keep calling the previous major version (`0.16.x`).

*See the full spec diff in `openapi.yaml`*.

```

## Summary

- **Version location**: The [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest file (e.g., [`plugins/zoom/.app.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.app.json)) contains the authoritative `version` field using semantic versioning (MAJOR.MINOR.PATCH).
- **Synchronization**: Always keep the OpenAPI spec ([`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml)) synchronized with the manifest version, ensuring breaking changes trigger major version bumps.
- **Publishing**: Use `opencode publish --manifest <path>` to deploy updates, with configuration defined in the root [`opencode.json`](https://github.com/openai/plugins/blob/main/opencode.json).
- **Execution tracking**: [`run_manifest.json`](https://github.com/openai/plugins/blob/main/run_manifest.json) captures the exact version used during each execution, enabling audit trails and version-drift detection as shown in the NGS-Analysis plugin documentation.
- **Breaking changes**: Maintain legacy versions during deprecation windows and implement version-aware routing to support gradual client migrations.

## Frequently Asked Questions

### What happens if I don't update the version field in .app.json?

The `opencode` CLI may reject your publish request or overwrite the existing version in the registry, causing inconsistent behavior for users who depend on specific versions. Always increment the version when modifying plugin functionality, even for documentation-only changes (PATCH level).

### How do I handle breaking API changes without disrupting existing users?

Increment the MAJOR version in your [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) and maintain the previous version's endpoints for a deprecation period (typically 30 days). Document the breaking changes in your [`README.md`](https://github.com/openai/plugins/blob/main/README.md) and provide migration instructions. Consider implementing version-aware middleware to route requests to the appropriate handler based on the `x-plugin-version` header.

### Can users request specific versions of my plugin?

Yes, consumers can specify which version to use during initialization. The system uses the `version` field from your [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) to match requested versions. Ensure your implementation handles the `x-plugin-version` header to serve the correct API contract, or maintain separate deployments for different major versions.

### Where is the version recorded during plugin execution?

The system generates a [`run_manifest.json`](https://github.com/openai/plugins/blob/main/run_manifest.json) file that captures the exact plugin version used for each execution, as demonstrated in the NGS-Analysis plugin's README at line 292. This allows you to audit which version produced specific results and to trigger re-runs if you need to upgrade or rollback to a different version.