Guide

A Storyblok deployment workflow that does not break production

Preview, staging, production — how content actually moves between them, what deployments copy, and what to do when the feature is not on your plan.

Last updated August 2026

Code has environments. Content usually does not, and that asymmetry is where accidents come from: an editor publishes to check a layout, and it is live. A deployment workflow fixes that by giving content the same forward-only path your code already has.

The shape of the workflow

Editors work here          Frozen            Frozen
┌───────────┐          ┌─────────┐       ┌────────────┐
│  Preview  │ ──────▶  │ Staging │ ────▶ │ Production │
└───────────┘  deploy  └─────────┘ deploy└────────────┘

Only Preview accepts edits. Everything downstream is read-only and changes only when you deploy into it. That single constraint is what removes merge conflicts from content entirely — promotion is always a fast-forward.

Step 1 — decide where each stage pulls from

A stage names its upstream with source_id. Two shapes are common, and both are valid:

ShapeLineageUse when
ChainPreview → Staging → ProductionYou want QA to sign off on exactly what ships
HubPreview → Staging, Preview → ProductionStages are independent previews for different audiences

The chain is the safer default: production receives content that has already sat in staging, rather than whatever is currently in Preview.

Step 2 — deploy into a stage

POST /v1/spaces/:space_id/deployments

{ "branch_id": 12345, "release_uuids": [] }
branch_id is the destination, not the source. Storyblok reads that stage’s source_id and copies content forward from there. You deploy a stage; you do not name a direction.

Leave release_uuids empty and the whole source stage moves. Supply specific releases and only those do, which is how you ship one campaign to production while unrelated work stays in staging.

What actually moves

  • Published content only. Drafts stay in Preview.
  • Story ids are reassigned in the target stage; uuid stays constant.
  • References are rewritten to the target stage’s ids.
  • Nothing flows backwards. A frozen stage cannot be edited and pushed upstream.

What does not move

  • Component schemas. These appear to be space-wide, so a breaking schema change reaches frozen production content immediately, with no deployment involved. Content is staged; structure is not.
  • Assets. Also space-wide, with stable URLs across stages.

Step 3 — point each site at its stage

Give every environment a delivery token bound to its stage. The frontend holds that token permanently and never names a branch, so a deployment changes what the site sees without any redeploy or config change:

EnvironmentTokenServes
Local / editor previewpreview tokenDraft and published
Staging sitestaging tokenWhatever was last deployed to staging
Live siteproduction tokenWhatever was last deployed to production

Rollback is the gap

Branch deployments are forward-only. There is no undo: if something wrong reaches production, recovery means fixing it in Preview and deploying again, with the bad content live in the meantime.

That is a consequence of how deployments store content — each stage holds its own copies, and deploying overwrites them. Systems that keep immutable content versions and move pointers instead can offer instant rollback, because the previous state was never destroyed.

If the feature is not on your plan

The /branches and /deployments endpoints require the Pipelines app. /stories and /api_keys do not, and that is enough to build the same workflow outside Storyblok.

Exacta does exactly that: editors keep working in your Storyblok space, Exacta mirrors its published content, and branches, promotion and per-branch tokens live on our side. Your frontend swaps api.storyblok.com for api.exacta.im and keeps the identical response shape.

Common questions

How do I deploy content from preview to staging in Storyblok?
POST to /v1/spaces/:space_id/deployments with the target stage as branch_id. Storyblok reads that stage’s source_id to decide where the content comes from, so you deploy the destination rather than naming a direction.
Does a Storyblok deployment move unpublished drafts?
No. Deployments move published content only. Drafts stay in the Preview stage until they are published.
Can I deploy only some content?
Yes. Pass release_uuids in the deployment payload and only those releases move, leaving other work in the source stage.
Can I roll back a Storyblok deployment?
No. Deployments are forward-only. Recovery means correcting content in Preview and deploying again.
Do component schema changes need a deployment?
No, and that is the risk. Components are space-wide, so a schema change affects every stage immediately including frozen production content.

Get branches back without upgrading.

Exacta adds dev, QA and staging branches to any Storyblok plan. Content stays in Storyblok; you point your frontend at a different base URL.

Start for Free