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

# Versioning & Publishing

> Understand how Jinba Toolbox manages immutable toolset versions with semantic versioning

## Overview

Jinba Toolbox uses a **semver-based versioning system** with immutable snapshots. Each toolset maintains a draft (the editable working copy) and a list of published versions. When you publish, a complete snapshot of the toolset -- including all tool code, schemas, and sandbox configuration -- is frozen as an immutable version that can never be modified.

This design ensures **reproducibility**: running version `1.0.0` always executes the same code, regardless of when or where it is called.

## Concepts

### Draft vs. Versions

```
ToolSet
├── Draft (editable working copy)
└── Versions (immutable releases)
    ├── v1.2.0 [published]
    ├── v1.1.0
    └── v1.0.0
```

| State         | Description                                                                                                  |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| **Draft**     | The editable working copy. Modified through the web UI or API. Can only be executed via the `test` endpoint. |
| **Version**   | An immutable release. Once published, it cannot be changed. Used by the `run` endpoint.                      |
| **Published** | The currently active version served by the API. One published version per toolset at a time.                 |

### Immutable Snapshots

Each version captures a complete snapshot of the toolset at the time of publishing:

* All tool code and entrypoints
* Input and output schemas
* Tool names and descriptions
* Sandbox configuration (provider, language, packages, resources)

This means even if you later update the draft, existing versions remain unchanged.

## Publishing Workflow

<Steps>
  <Step title="Edit the draft">
    Make changes to tools in the draft through the web console or the API. Use the test endpoint to verify behavior:

    ```bash theme={null}
    curl -X POST https://toolbox-api.jinba.dev/v1/orgs/{orgId}/toolsets/slack-tools/tools/post-message/test \
      -H "Authorization: Bearer jtb_xxxxxxxxxxxx" \
      -H "Content-Type: application/json" \
      -d '{ "input": { "channel": "#test", "text": "Testing..." } }'
    ```
  </Step>

  <Step title="Publish a new version">
    When the draft is ready, publish it with a semver version number and optional release notes:

    ```bash theme={null}
    curl -X POST https://toolbox-api.jinba.dev/v1/orgs/{orgId}/toolsets/slack-tools/versions \
      -H "Authorization: Bearer jtb_xxxxxxxxxxxx" \
      -H "Content-Type: application/json" \
      -d '{
        "version": "1.3.0",
        "releaseNotes": "Added thread reply support"
      }'
    ```

    Or using the SDK:

    ```typescript theme={null}
    const version = await client.publishVersion("slack-tools", {
      version: "1.3.0",
      releaseNotes: "Added thread reply support",
    });
    ```
  </Step>

  <Step title="Set the published version">
    Choose which version the API should serve. Newly published versions do not automatically become the active version -- you must explicitly set it:

    ```bash theme={null}
    curl -X PUT https://toolbox-api.jinba.dev/v1/orgs/{orgId}/toolsets/slack-tools/published-version \
      -H "Authorization: Bearer jtb_xxxxxxxxxxxx" \
      -H "Content-Type: application/json" \
      -d '{ "version": "1.3.0" }'
    ```

    The change takes effect immediately.
  </Step>

  <Step title="Continue developing">
    The draft remains intact after publishing, so you can keep iterating on the next version without affecting the live published version.
  </Step>
</Steps>

## Version Resolution

When a tool is executed via the `run` endpoint, Jinba Toolbox resolves which version to use:

1. If the request body includes a `version` field, that exact version is used.
2. Otherwise, the currently published (active) version is used.

```bash theme={null}
# Uses the published version
curl -X POST .../tools/post-message/run \
  -d '{ "input": { "channel": "#general", "text": "Hello" } }'

# Uses a specific version
curl -X POST .../tools/post-message/run \
  -d '{ "input": { "channel": "#general", "text": "Hello" }, "version": "1.2.0" }'
```

## Rollback

Rolling back is simply a matter of changing the published version to a previous one:

```bash theme={null}
# Switch back to v1.2.0
curl -X PUT https://toolbox-api.jinba.dev/v1/orgs/{orgId}/toolsets/slack-tools/published-version \
  -H "Authorization: Bearer jtb_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "version": "1.2.0" }'
```

Because versions are immutable, no data is lost during a rollback. The newer version remains available and can be re-activated at any time.

## Version API

| Method | Endpoint                                           | Description                      |
| ------ | -------------------------------------------------- | -------------------------------- |
| GET    | `/v1/orgs/:orgId/toolsets/:slug/versions`          | List all versions                |
| POST   | `/v1/orgs/:orgId/toolsets/:slug/versions`          | Publish a new version            |
| GET    | `/v1/orgs/:orgId/toolsets/:slug/versions/:version` | Get version details              |
| PUT    | `/v1/orgs/:orgId/toolsets/:slug/published-version` | Set the active published version |

## Version Data Model

Each published version stores a full snapshot:

```typescript theme={null}
interface ToolSetVersion {
  id: string;
  toolSetId: string;
  version: string;              // Semver string (e.g., "1.3.0")
  sandbox: SandboxConfig;       // Frozen sandbox configuration
  tools: ToolSnapshot[];        // Frozen tool definitions and code
  releaseNotes?: string | null;
  publishedBy: string;          // User ID of the publisher
  publishedAt: string;          // ISO 8601 timestamp
}

interface ToolSnapshot {
  id: string;
  slug: string;
  name: LocalizedText;
  description: LocalizedText;
  inputSchema: JSONSchema;
  outputSchema: JSONSchema;
  code: string;
  entrypoint?: string;
}
```

## Usage Tracking

Jinba Toolbox tracks API call counts per version. You can view usage statistics in the web console or retrieve run history through the API:

```typescript theme={null}
const runs = await client.listRuns();
// Filter by version in your application logic
```

Usage data helps you determine when it is safe to deprecate older versions.

## Best Practices

* **Follow semantic versioning** -- use major bumps for breaking schema changes, minor bumps for new tools or features, and patch bumps for fixes.
* **Write release notes** -- they help your team understand what changed between versions.
* **Test before publishing** -- use the `test` endpoint to validate the draft before creating an immutable version.
* **Do not skip the publish step for MCP** -- MCP endpoints serve the published version, not the draft.
* **Monitor per-version usage** -- before deprecating a version, verify that no consumers still depend on it.

## Related

* [REST API](/en/pages/toolbox/developer/api) -- Full endpoint reference including version routes
* [SDK](/en/pages/toolbox/developer/sdk) -- Programmatic version management
* [Security & Access Control](/en/pages/toolbox/advanced/security) -- Who can publish versions
