Storyblok Raises $80M Series C - Read News

Skip to main content
  • Docs
  • Guide
  • Handling content using the management API

Handling content using the Management API


On May 13th, 2024, Storyblok started gradually rolling out a new design for its Visual Editor. Therefore, the Visual Editor product screenshots depicted in this resource may not match what you encounter in the Storyblok App. For more information and a detailed reference, please consult this FAQ on the new Visual Editor design.

Section titled What is the Management API?

Our Management API allows deep integration with the CMS. It offers a programmatic approach to creating and updating your content.
The Storyblok Management API is based on REST. It allows you to create, edit, and update content using a common interface.

As part of the Management API's role, it offers export/import CSV, upload assets, and migrations. You will find all these examples in this documentation.

Section titled Basic URL

Basic URL

You should not expose your secret API key in any public website's client-side code.


Storyblok API libraries convert responses to appropriate language-specific objects.

Samples of the requests are on our Management API Reference page.

Use our sample requests with the API Authentication Token from your profile in the Storyblok application to test out the Management API. We explain more, including how to generate your own API Authentication Token, in the Authenticate with your OAuth token section.


See more details in our Management API documentation page.

Section titled Management API use cases

  • Migration from your current data storage / CMS
  • Integration with 3rd party applications
  • Import and Export automation
  • Automatic translation workflows
  • Component versioning
  • Whitelabel integrations

Storyblok's Management API should be avoided if you intend to serve this content to your audience. This is because the Storyblok Management API doesn't utilize our global CDN for your requests. In this case, use Content Delivery API.

Use cases
StoriesCan be used to import, export, or modify content.
ComponentsCan be nested in each other. Consists of fields types.
Component GroupsCan be used to group components together.
AssetsEach asset object references one of the uploaded images, videos, and documents.
Asset FoldersCan be used to group assets together.
DatasourcesCan be used as a single or multiple choice for multi-language labels, categories, or anything similar to these.
Datasource EntriesEach datasource entry is a set of an object which consists of a key and the value.
SpacesCan be used as a content repository to keep all relevant content in one place.
Space RolesCan be attached to collaborators to define their roles and permissions in dedicated spaces.
TasksCan be used for triggering builds, product sync, and publishing tasks to send requests to one of the custom endpoints.
ApprovalsCan be used to send approval requests to another collaborator of the space.
ActivitiesCan be created on an update, create and delete actions in Storyblok resources. (i.e. stories, components, spaces, datasources, etc)
PresetsCan be used to define multiple default values for components. (i.e. multiple styles in one component)
Field typesCan be used to extend the editor. (i.e. color picker, google map location selector, etc)
Workflow StageCan be used to define workflow stages and rules to control what each user is allowed to do.
Workflow Stage ChangesCan be the objects that are assigned to a dedicated content item.
ReleasesThe response can be a release object. (i.e. id, name, release_at, branches_to_deploy)
Branch deploymentsThe end point can be used to deploy branches. (/v1/spaces/:space_id/deployments)

Section titled Authenticate with your OAuth token

Generate your API Authentication Token from your profile page. Go to the My Account, Account settings{1} and Personal access tokens{2}. Click Generate new Token{3} button.

My account screen to generate a new token

My account screen to generate a new token

Section titled Export or Import a CSV into a folder

To export or import a CSV into a folder in Storyblok, we offer you a Node.js Script that allows you to do that.

Section titled The architecture of export/import

The Node.js script checks for column values. The values starting with http will be detected. Node.js Scripts will download the original file into the ./images/ folder to upload those files to Storyblok.

  • Use case 1: Export data from Storyblok as CSV
  • Use case 2: Import data to Storyblok from CSV

Configuration options for the config.js file are below.

      module.exports = {
  storyblok: {
    export: {
      previewToken: 'YOUR_PREVIEW_TOKEN',         // for export -> Delivery API
      options: {                                  // Content Delivery Parameters
        // starts_with: '/your-folder-slug',      // folder you want to export as CSV,
        version: 'draft',                         // version of content that should be exported
        per_page: 100,                            // 100 is max atm
        page: 1                                   // can be upped as needed.
    import: {
      oauthToken: 'YOUR_OAUTH_MANAGEMENT_TOKEN',  // for import -> Management API,
      spaceId: 83418,                             // Space ID you want to import it
      parentFolderId: 0,                          // Folder of the Parent ID
      importFilePath: './import/import.csv',      // File that should be imported 


To export data from Storyblok as a CSV, configure the previewToken with the preview token of the space. The export will be served at /export/<timestamp>.csv.

As a final step, execute the command below.

      npx run export


Import data to Storyblok from the CSV by obtaining the OAuth token as described in Authenticate with your OAuth token section. After filling out the suitable values in the config.js file, execute the command below.

      npx run import

You can take a look at our GitHub repository about Storyblok import and export for more information.

      curl "" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_OAUTH_TOKEN" \
  -d "{\"filename\":\"your_file.jpg\",\"size\":\"400x500\"}"
     'spaces/656/assets/', {
  "filename": "your_file.jpg",
  "size": "400x500"
}).then(response => {
}).catch(error => { 

Here are example requests utilizing an asset folder.

      curl "" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_OAUTH_TOKEN" \
  -d "{\"filename\":\"your_file.jpg\",\"size\":\"400x500\",\"asset_folder_id\":123}"
     'spaces/606/assets/', {
  "filename": "your_file.jpg",
  "size": "400x500",
  "asset_folder_id": 123
}).then(response => {
}).catch(error => { 

Section titled Post the image as form data to our Amazon S3 bucket.

Upload files, to complete the process, by using the received response. For example, you can use Node.js for that. With Node.js, you can use the Storyblok Management API to upload files by using a signed request. The example code is combined together with step 3 below.

Section titled Send another request to complete the process.

Storyblok retrieves the MIME type and the content length for assets.

      const FormData = require('form-data')
const fs = require('fs')

const file = '/path_to/your_file.jpg'
const fileUpload = (signed_response_object, success, failed) => {
  let form = new FormData()
  // Step 2. apply all fields from the signed response object to the second request
  for (let key in signed_response_object.fields) {
    form.append(key, signed_response_object.fields[key])
  // Step 2. also append the file read stream
  form.append('file', fs.createReadStream(file))
  // submit your form
  form.submit(signed_response_object.post_url, (err, res) => {
    if (err) throw err
    // Step 3. complete the upload
    Storyblok.get('spaces/606/assets/' + + '/finish_upload').then(response => {
      console.log('' + signed_response_object.fields.key + ' uploaded!')
    }).catch(error => { 
      throw error
    console.log('' + signed_response_object.fields.key + ' uploaded!')

For more details, go to our Storyblok Management API documentation.


Use Promise Throttle (an NPM package) to limit promises run per unit time for rate-limited requests in a set amount of time.


Use async (an NPM package) together with Promise Throttle to provide functions for working with asynchronous JavaScript.

Section titled Migration use cases

Storyblok's Management API and automation can be used for migrations. Examples of migrations include:

Migration examples
Change an image fieldMake changes to the image field in the product component.
Transform a Markdown field into a Richtext fieldTransform a Markdown or HTML field into Richtext.
Migrate spacesRun and rollback migrations through Storyblok CLI.
Import space schemasImport components schema as JSON.
Version spaces locally & Edit content in a local editorEdit content in local text editor and push into Storyblok.
Update a StoryRequest to update a Story.
Migrate content between languagesDefine slugs for folders and stories in different languages.
Migrate from WordPress to StoryblokMigrate contents from monolithic to headless CMS, Storyblok

Take a look at our Storyblok CLI for more details of these examples.

Section titled How to migrate spaces

Content migrations conveniently allow you to change fields of content. To migrate spaces, we recommend you use our new content migration feature from the Storyblok CLI.

There are 4 steps to migrate.

Section titled Creating a migration file

Execute the generate-migration command to create a migration file. To migrate spaces, there is an option of space for generate-migration.

      $ storyblok generate-migration --space <SPACE_ID> --component <COMPONENT_NAME> --field <FIELD>

A sample file will be created in the folder of migrations that looks like below.

      module.exports = function (block) {
  // change a string to boolean
  // block.subtitle = !!(block.subtitle)

  // transfer content from other field
  // block.subtitle = block.other_field

You can manipulate the block variable to add or modify existing fields of the component in this migration function.

Section titled Running the migration file

Execute run-migration command to run the migration file.

      $ storyblok run-migration --space <SPACE_ID> --component <COMPONENT_NAME> --field <FIELD>

There is a —dryrun option to prevent executing updates and only show the changes in the command line.

      $ storyblok run-migration --space <SPACE_ID> --component <COMPONENT_NAME> --field <FIELD> --dryrun

Section titled Publishing the content

To publish content, you can use —publish and —publish-languages options.

  • —publish option: Specify one of the options.
    • all
    • published
    • published-with-changes
  • —publish-languages=<LANGUAGE>: Specify the language to update.
  • —publish-languages=ALL_LANGUAGES: Update all languages.

Section titled Rollback migrations

By running the run-migrations command, a JSON file containing all the content before the change will be generated.

      $ storyblok rollback-migration --space <SPACE_ID> --component <COMPONENT_NAME> --field <FIELD>

Rollback migrations don't apply with —dryrun flag.


The saved content is always related to the last run-migration command.

Section titled How to export and import space schemas

Download your space's components schema as JSON. The pull-components command from Storyblok CLI will download 2 files to your local environment:

  • A file for components
  • A file for presets
      $ storyblok pull-components --space <SPACE_ID>

To import, use the push-components command from Storyblok CLI. It allows you to push your components file to a space.

      $ storyblok push-components <SOURCE> --space <SPACE_ID> --presets-source <PRESETS_SOURCE>

Section titled How to version space locally and edit component schemas

Download the schemas with Storyblok CLI's pull-components to edit content in the local editor, and push it into Storyblok with Storyblok CLI's push-components command as described in the How to import space schemas section. It allows you to download JSON files in order to edit them locally and push them to Storyblok.

Section titled How to Update a Story

If you change your component architecture or need to do a bulk action on all your content items, you can also build migrations by updating a Story. Example requests with curl and JavaScript are below. You can add the property "publish": 1 to the object to publish Stories immediately.

      curl "" \ 
  -X PUT \
  -H "Authorization: YOUR_OAUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"story\":{\"name\":\"Story Name\",\"slug\":\"story-name\",\"id\":2141,\"content\":{\"component\":\"page\",\"body\":[]}},\"force_update\":1,\"publish\":1}"

      // use the universal js client to perform the request
Storyblok.put('spaces/606/stories/2141', {
  "story": {
    "name": "Story Name",
    "slug": "story-name",
    "id": 2141,
    "content": {
      "component": "page",
      "body": []
  "force_update": 1,
  "publish": 1
}).then(response => {
}).catch(error => { 

The property force_update will overwrite a locked story.

Here is the list of all the properties and descriptions.

Stories - Update a Story
storyFull story object.
story[name]Name of the story is required.
story[slug]Slug is required. Can be used to identify the Story.
story[content]Object structure for content.
story[default_root]Default content type/root component. If is_folder is true, this is required.
story[is_folder]A folder will be created if the value is true.
story[parent_id]The id of the parent.
story[disable_fe_editor]Side by side editor will be disabled for all entries in a folder.
story[path]Can be used in the preview editor.
story[is_startpage]Startpage of the current folder.
story[position]Integer value of the position.
story[first_published_at]First publishing date. (YYYY-mm-dd HH:MM)
story[translated_slug_attributes]Can be used to add/modify/delete translated slugs/names if Translatable slugs app is installed.
force_updateCan be used to overwrite a locked Story if the value is 1.
release_idNumeric ID of release. (optional)
publishCan be used to publish a Story if the value is 1.
langLanguage code to publish the story individually. Enable it in the space settings.

The example of story[translated_slugs_attributes] can be[{lang: "de", slug: "startseite", name: "Startseite"}].


For more details, you can read Storyblok Management API documentation.

Section titled Migrate content between languages

With Translatable Slugs app in the Storyblok App Store, you can define slugs for folders and stories in different languages. Take a look at our Internationalization documentation page for more information.


Translatable slug for entry is for field-level translation. For more information, take a look at our Translatable slugs section.


Meta information is not translatable.


There's Storyblok awesome repo to see useful migration packages.

Section titled Migrate content from WordPress to Storyblok

With the WordPress Importer for Storyblok plugin, you can migrate content from WordPress to Storyblok.

In order to use the script from WordPress Importer for Storyblok, import the script and initialize a new instance of the WP2Storyblok class. You can then run the WP2Storyblok.migrate() method. See the example below.

      import {Wp2Storyblok} from './index.js'

const wp2storyblok = new Wp2Storyblok('', {
  token: 'storyblok-oauth-token',
  space_id: 110836,
  content_types: [
      name: 'pages',
      new_content_type: 'page',
      folder: 'your-custom-folder',
      schema_mapping: {
        title: 'name',
        '_links.wp:featuredmedia.0': 'content.preview_image',
        content: {
          field: 'content.body_items',
          component: 'rich-text',
          component_field: 'content'


WordPress REST API must be publicly available during the migration process as the script from WordPress Importer for Storyblok won't handle authentication.


Find more information about our WordPress Importer for Storyblok GitHub repository.