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:
publishing from the Studio freezes the workflow's slug under its organization,
and from then on the address permanently identifies that workflow — the slug
does not change when the workflow's display name does, and it is never
re-registered for a different workflow. Deleting a published workflow retires
its name forever: the slug is tombstoned and can never be claimed by another
workflow in the organization, so an old address can never start resolving to
something else. An 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, getWorkflow } from "@blitflow/sdk";
const client = new BlitClient({ apiKey: process.env.BLITFLOW_TOKEN });
const { id, version, sequence, workflow } = await getWorkflow(
client,
"acme/sprite-pack@2",
);