Handling content using the management API

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.

Basic URL

Basic URL
https://mapi.storyblok.com

WARN:

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

HINT:

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.

HINT:

See more details in our Management API documentation page.

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

WARN:

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
Stories Can be used to import, export, or modify content.
Components Can be nested in each other. Consists of fields types.
Component Groups Can be used to group components together.
Assets Each asset object references one of the uploaded images, videos, and documents.
Asset Folders Can be used to group assets together.
Datasources Can be used as a single or multiple choice for multi-language labels, categories, or anything similar to these.
Datasource Entries Each datasource entry is a set of an object which consists of a key and the value.
Spaces Can be used as a content repository to keep all relevant content in one place.
Space Roles Can be attached to collaborators to define their roles and permissions in dedicated spaces.
Tasks Can be used for triggering builds, product sync, and publishing tasks to send requests to one of the custom endpoints.
Approvals Can be used to send approval requests to another collaborator of the space.
Activities Can be created on an update, create and delete actions in Storyblok resources. (i.e. stories, components, spaces, datasources, etc)
Presets Can be used to define multiple default values for components. (i.e. multiple styles in one component)
Field types Can be used to extend the editor. (i.e. color picker, google map location selector, etc)
Workflow Stage Can be used to define workflow stages and rules to control what each user is allowed to do.
Workflow Stage Changes Can be the objects that are assigned to a dedicated content item.
Releases The response can be a release object. (i.e. id, name, release_at, branches_to_deploy)
Branch deployments The end point can be used to deploy branches. (/v1/spaces/:space_id/deployments)

Authenticate with your OAuth token

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

https://app.storyblok.com/#!/me/account My account screen to generate a new token

My account screen to generate a new token

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.

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.

config.js
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 
    }
  }
}

Export:

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:

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
HINT:

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

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

Here are example requests utilizing an asset folder.

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

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.

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/' + signed_response_object.id + '/finish_upload').then(response => {
      console.log('https://a.storyblok.com/' + signed_response_object.fields.key + ' uploaded!')
    }).catch(error => { 
      throw error
    })
    console.log('https://a.storyblok.com/' + signed_response_object.fields.key + ' uploaded!')
  })
}
HINT:

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

HINT:

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

HINT:

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

Migration use cases

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

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

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

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.

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.

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

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.

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>
WARN:

Rollback migrations don’t apply with —dryrun flag.

HINT:

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

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>

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.

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 "https://mapi.storyblok.com/v1/spaces/606/stories/2141" \ 
  -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 => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})

The property force_update will overwrite a locked story.

Here is the list of all the properties and descriptions.

Stories - Update a Story
story Full 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_update Can be used to overwrite a locked Story if the value is 1.
release_id Numeric ID of release. (optional)
publish Can be used to publish a Story if the value is 1.
lang Language 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"}].

HINT:

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

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.

HINT:

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

WARN:

Meta information is not translatable.

HINT:

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

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('http://yoursite.com/wp-json', {
  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'
        }
      }
    }
  ]
})

wp2storyblok.migrate()
WARN:

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

HINT:

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