Versioning
Immutable published versions, semver selectors, and the @latest pointer.
Publishing a workflow from the Studio editor creates an immutable version: a frozen snapshot of the definition, addressed by semver. Your integrations run against these versions — the editor's draft state never changes a published version underneath you.
Version references
Everywhere a workflow reference is accepted (workflowRef on runs, the SDK's
run/getWorkflow, MCP tools, the CLI's run), the notation is
<id>@<version>. The id half takes two forms:
- Published address (preferred):
<org-slug>/<workflow-slug>, e.g.acme/sprite-pack— see Published addresses below. - Workflow UUID (internal form, still accepted everywhere), e.g.
8f61e451-40a7-4f65-8fa9-69704576b6d4.
| Reference | Resolves to |
|---|---|
acme/sprite-pack | Latest version (implicit @latest) |
acme/sprite-pack@latest | The current latest pointer (see below) |
acme/sprite-pack@2.1.0 | Exactly version 2.1.0 |
acme/sprite-pack@2 | The highest published 2.x.x |
The same selectors work with the UUID form
(8f61e451-40a7-4f65-8fa9-69704576b6d4@2.1.0).
Partial versions like @2.5 are rejected as ambiguous — use a full semver
(@2.5.0) or a bare major (@2).
Over raw HTTP the same selectors appear as a query parameter:
GET /v1/workflows/acme%2Fsprite-pack?version=2.1.0 — the address's / is
URL-encoded in the path (see the endpoint reference).
Published addresses
A workflow's address is <org-slug>/<workflow-slug>, both in kebab-case
(lowercase letters, digits, -). The first publish claims the slug, and
from then on the address permanently identifies that workflow:
- Renaming the workflow's display name does not change the slug.
- Deleting a published workflow retires its name forever — the slug is tombstoned and never re-registered, so an old address can never start resolving to a different workflow.
- The organization's own slug is likewise frozen once it namespaces any published workflow.
- Platform namespaces (
blitflow,core, and a few others) are reserved and can never be org slugs.
The address resolves wherever a workflow ref is accepted — the HTTP API, the SDK, the MCP tools, and the CLI. The UUID remains the internal id (it appears in run details and observability) and keeps working as a ref forever.
Semver and the latest pointer
- Versions are
MAJOR.MINOR.PATCH(no prerelease/build tags). When publishing, you choose which component to bump. - Versions are immutable; the definition behind
2.1.0never changes. @latestis a mutable pointer. It normally tracks the newest publish, but can be rolled back in the Studio to point at an earlier version — without deleting anything. New version numbers always continue from the highest ever published, so rollbacks never cause collisions.- Each response from
workflows.getalso carries a monotonically increasingsequencenumber, useful for detecting "did anything change" regardless of semver.
Choosing a selector
| Use case | Recommended ref |
|---|---|
| Production integration, no surprises | Exact — acme/sprite-pack@2.1.0 |
| Track compatible updates within a major | Major — acme/sprite-pack@2 |
| Internal tools, always newest | acme/sprite-pack@latest |
Pin exact versions in production: @latest and @2 both move when new
versions are published (or @latest is rolled back).
Fetching a published definition
You can fetch the canonical JSON of any published version — useful for auditing, diffing, or running it locally as an inline workflow:
import { BlitClient } from "@blitflow/sdk";
const client = new BlitClient({ apiKey: process.env.BLITFLOW_TOKEN });
const { id, version, sequence, workflow } =
await client.getWorkflow("acme/sprite-pack@2");