Guide
Storyblok Pipelines, explained
What pipeline stages actually are, the one rule that governs all of them, and why the API is gated behind a paid app.
Last updated August 2026
Storyblok Pipelines let you stage content: edit in one place, then push it forward through environments before it reaches your live site. If you have ever published a half-finished page by accident, this is the feature you were missing.
It is also the feature most teams discover they do not have. Pipelines is a separate app, and the Management API endpoints that drive it refuse to work until it is installed on the space.
Pipelines and Branches are the same thing
Storyblok renamed the Branches app to the Pipeline app. Their stated reason: “Branches” led people to expect Git-like behaviour, which is not what these are.
The API kept the old noun. You will see both names in the same project — the UI says Pipelines, the endpoint is still /v1/spaces/:id/branches. That mismatch confuses almost everyone the first time.
| Term | What it means |
|---|---|
| Pipeline | The whole staging workflow for a space |
| Pipeline stage | One step in it — Preview, Staging, Production |
| Branch | The old name for a stage. Still the API resource name. |
The one rule that governs everything
This is the difference that matters, and it is not a limitation Storyblok failed to overcome — it is the decision that makes staged content workable at all. With exactly one writable stage, promotion is always a fast-forward, so merge conflicts cannot occur. Allow editing in two stages and you have signed up for three-way merge resolution, which is a far harder problem.
| Git branches | Pipeline stages | |
|---|---|---|
| Where you edit | Any branch | Preview only |
| Direction | Bidirectional, merge back | One-way, forward only |
| Conflicts | Normal | Impossible |
| Purpose | Parallel development | Sequential content staging |
How a stage is wired
Each stage names the stage it pulls from, via source_id. The result is a chain rooted at Preview:
Preview → Staging → Production
(editable) (frozen) (frozen)A branch object from the Management API looks like this:
{
"id": 12345,
"name": "Production",
"space_id": 98765,
"source_id": 12344, // the stage this one deploys FROM
"url": "https://www.site.com",
"position": 2,
"environment": "production",
"deployed_at": "2026-07-30T09:12:44Z"
}Promotion is inverted from how people expect
You do not say “promote Preview to Staging”. You say “deploy Staging”, and the stage’s own source_id decides where the content comes from:
POST /v1/spaces/:space_id/deployments
{ "branch_id": 12345, "release_uuids": ["1234-4567"] }branch_id is the destination. Omit release_uuids and the whole source stage moves; supply them and only those releases do — that is how you ship one campaign to production while other work waits in staging.
The identity rule that breaks integrations
id changes between pipeline stages. Its uuid is stable. Track content across stages by uuid, never by id.Each stage holds physically separate story rows with their own primary keys. Anything that carries an id across a stage boundary — aparent_id, a relation field, an internal link — points at the wrong entry or nothing at all. Reference rewriting is the single largest source of bugs in any content-sync code.
What the plan actually gates
To use the branches and deployments endpoints, the Pipelines app must be installed on the space. That splits the API cleanly:
| Capability | Endpoint | Available without the app? |
|---|---|---|
| Read and write content | /v1/spaces/:id/stories | Yes |
| Manage delivery tokens | /v1/spaces/:id/api_keys | Yes |
| Branches | /v1/spaces/:id/branches | No |
| Deployments | /v1/spaces/:id/deployments | No |
So the workarounds teams reach for — duplicating spaces, copying stories by hand, keeping a spreadsheet of what has shipped — exist because the primitive they need is behind a paywall, not because they enjoy manual work.
Components are not staged
One thing worth designing around: component schemas appear to be space-wide rather than per-stage. Content is staged; structure is not. A breaking schema change reaches your frozen production content immediately, with no deployment involved.
Getting staging without the add-on
Because /stories and /api_keys stay open on every plan, staging can be rebuilt outside Storyblok. That is what Exacta does: your space stays the single place anyone edits, Exacta mirrors its published content, and branches plus promotion live on our side. Your frontend changes one base URL and keeps the same response shape.
Common questions
- Are Storyblok Pipelines and Branches different features?
- No. Storyblok renamed the Branches app to the Pipeline app because "branches" implied Git-like behaviour. The API resource is still called branches, so you will see both names for the same feature.
- Can I edit content directly in a staging pipeline stage?
- No. A pipeline is one-way: content is editable only in the Preview stage and frozen everywhere else. That is what makes promotion conflict-free.
- Why does a story have a different id in each stage?
- Each pipeline stage holds its own physical story rows with their own primary keys. The uuid is stable across stages and is the only safe way to track a story between them.
- Can I use the branches API without the Pipelines app?
- No. The branches and deployments endpoints require the Pipelines app to be installed on the space. The stories and api_keys endpoints remain available on every plan.
- Can I roll back a Storyblok deployment?
- Not directly. Branch deployments are forward-only. Recovery means correcting the content in Preview and deploying again.