Managing Stories

The Stories endpoint will let you manage all content entries of your Storyblok space. You can use it to import, export or modify content.

Following an example of using Storyblok’s Javascript client to sync the content of a folder from one space to another:

const StoryblokClient = require('storyblok-js-client')

// Insert your oauth token from the my account section
const Storyblok = new StoryblokClient({
  oauthToken: 'OAUTH_TOKEN'
})

// Insert your source space and folder id
const spaceId = '44953'
const folderId = '126982'

// Insert your target space and folder id
const targetSpaceId = '49927'
const targetFolderId = '425533'

const StoryblokExporter = {
  getAll(page) {
    return Storyblok.get('spaces/' + spaceId + '/stories', {
      per_page: 25,
      with_parent: folderId,
      page: page
    })
  }
}

async function getAllStories(){
  var page = 1
  var res = await StoryblokExporter.getAll(page)
  var all = res.data.stories
  var total = res.total
  var lastPage = Math.ceil((res.total / 25))

  while (page < lastPage){
    page++
    res = await StoryblokExporter.getAll(page)
    res.data.stories.forEach((story) => {
      all.push(story)
    })
  }

  for (var i = 0; i < all.length; i++) {
    console.log(all[i].name)
    try {
      all[i].parent_id = targetFolderId
      let res = await Storyblok.post('spaces/' + targetSpaceId + '/stories', {
        story: all[i]
      })
    } catch(e) {
      console.log(e.response.data)
    }
  }

  return all
}

getAllStories().then((result) => {
  console.log('Finished')
})

Creating a Story via the API

To create a new content item (Story) you need to provide at least the name and slug attribute under the “story” object. In the content attribute you can put all the data that’s individual to each content type. The content type is identified by the content.component attribute.

The content attribute

You can save any data in the content attribute as long as you follow this rules:

  • The content attribute needs to be an object at the root level
  • Every object inside needs to have the attribute “component”
  • Only nest components using arrays

This let’s you import data and define the schema afterwards through the interface where necessary.

let res = await Storyblok.post('spaces/' + targetSpaceId + '/stories', {
  story: {
    name: "Article 1",
    slug: "article-1",
    content: {
      component: "news",
      headline: "This is awesome!",
      body: [{
        component: "download_link",
        file: "//a.storyblok.com/.../news.pdf"
      }]
    }
  }
})

Internationalization

If you use field level translations you can provide the values for the translations within the same content object by appending __i18n__ followed by the language iso code. Following an example:

let res = await Storyblok.post('spaces/' + targetSpaceId + '/stories', {
  story: {
    name: "Article 1",
    slug: "article-1",
    content: {
      component: "news",
      headline: "This is awesome!",
      headline__i18n__de: "Das ist toll!",
    }
  }
})

API-Endpoints

Following the API-Endpoints that you can use to manage Stories.

Getting a list of stories

Endpoint

GET /v1/spaces/:space_id/stories

Parameters

Name Description
page Current page of stories
contain_component Filters by component in all levels of the content. Allows comma separated value for multiple components
search_term Filter by a term using full text search
sort_by Sort entries by specific attribute and order with 'content.YOUR_FIELD:asc' and 'content.YOUR_FIELD:desc'. Possible values are all root attributes of the entry (position and parent_position are special invisible attributes) and all fields of your content type inside 'content' with the dot as seperator. Example: 'position:asc', 'parent_position:asc', 'content.your_custom_field:asc', 'created_at:desc'
pinned Filter by pinned stories if '1'
excluding_ids Exclude stories by ids (comma separated) from result
by_ids Filter by ids (comma separated)
by_uuids Filter by uuids (comma separated)
with_tag Filter by tag
folder_only Filter by folders only
story_only Filter by stories only
with_parent Filter by parent id
with_slug Filter by exact slug
starts_with Filter stories starting with a specific slug
in_trash Filter by items in the trash folder
search Filter by search term
filter_query Filter by specific attribute(s) of your content type. See content delivery api documentation.

Request

Query Parameters

page=0
contain_component=headline
sort_by=lower(stories.name):asc

cURL

curl "https://api.storyblok.com/v1/spaces/684/stories?page=0&contain_component=headline&sort_by=lower%28stories.name%29%3Aasc" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTI0LCJ0aW1lc3RhbXAiOjE1NDI0Njg4MDh9.EM7H6_6GtWFEKIs1qRK9ZsVFKTQzXsb_Zdejs-Fu77o" \

Response

Body

{
  "stories": [
    {
      "name": "Test",
      "parent_id": 0,
      "created_at": "2018-11-10T15:33:28.776Z",
      "deleted_at": null,
      "group_id": "c029b5d3-8a3a-4f76-9f7f-af4c05d4efb1",
      "sort_by_date": null,
      "updated_at": "2018-11-10T15:33:28.776Z",
      "published_at": null,
      "id": 1196,
      "uuid": "6c714bd6-84c1-4727-97ed-48e7d6f07d78",
      "is_folder": false,
      "published": false,
      "slug": "test",
      "path": null,
      "full_slug": "test",
      "position": 0,
      "unpublished_changes": null,
      "is_startpage": false,
      "pinned": false,
      "publish_at": null,
      "expire_at": null,
      "first_published_at": null,
      "release_ids": [

      ]
    }
  ]
}

Get a single story

Endpoint

GET /v1/spaces/:space_id/stories/:id

Request

cURL

curl "https://api.storyblok.com/v1/spaces/683/stories/1195" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTIxLCJ0aW1lc3RhbXAiOjE1NDI0Njg4MDh9.G2L6oYCG0sdIYfsPeAvmAXvCeXQQWaOjcGUmPfcxatU" \

Response

Body

{
  "story": {
    "name": "Home",
    "parent_id": 0,
    "group_id": "fb6bcc85-7e4b-47a5-acd0-fba6d54df042",
    "alternates": [

    ],
    "created_at": "2018-11-10T15:33:28.480Z",
    "sort_by_date": null,
    "tag_list": [

    ],
    "updated_at": "2018-11-10T15:33:28.576Z",
    "published_at": null,
    "id": 1195,
    "uuid": "be77cb02-a16e-47af-afe5-6a8436b664e2",
    "is_folder": false,
    "content": {
      "_uid": "xyz",
      "body": [
        {
          "_uid": "a9e16ab8-887f-4001-9548-313a09daeb2a",
          "text": "test1",
          "component": "headline"
        },
        {
          "_uid": "89a3cd23-8fd1-4ddc-abfe-a6396d012d14",
          "text": "test2",
          "component": "headline"
        }
      ],
      "component": "root"
    },
    "published": false,
    "slug": "home",
    "path": null,
    "full_slug": "home",
    "default_root": null,
    "disble_fe_editor": false,
    "parent": null,
    "is_startpage": false,
    "unpublished_changes": null,
    "meta_data": null,
    "imported_at": null,
    "preview_token": {
      "token": "",
      "timestamp": "1541864008"
    },
    "pinned": false,
    "breadcrumbs": [

    ],
    "publish_at": null,
    "expire_at": null,
    "first_published_at": null,
    "last_author": null
  }
}

Creating an story

Stories are not published by default. If you want to create a published Story add the parameter publish=1.

Endpoint

POST /v1/spaces/:space_id/stories

Parameters

Name Description
publish If '1' the story will be published immediately after creating
story[name] required Name of the story
story[slug] required Slug to be used to receive the story from the api
story[content] JSON tree of the content
story[disble_fe_editor] Whether to disable the visual editor
story[default_root] Default root component. (Required if a folder story)
story[is_folder] Whether the story acts as a folder
story[group_id] Group ID. For example to make linkages between language versions
story[path] Url path the editor is opening the story
story[is_startpage] Whether the story is a startpage for this folder
story[parent_id] Id of the parent folder
story[sort_by_date] Sort by date
story[first_published_at] First published date
story[meta_data] Key value pairs to add meta data that is not setting the story status to unpublished changes. Example: User ratings.
story[pinned] To pin the story in the toolbar

Request

cURL

curl "https://api.storyblok.com/v1/spaces/687/stories" -d '{"story":{"name":"Story 1","content":{"component":"root","body":[]},"path":"/v1/spaces/687/stories"}}' -X POST \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTMzLCJ0aW1lc3RhbXAiOjE1NDI0Njg4MDl9.ENjpOyg12msMkRgsKMF5KvaATDn4XAOqxzV-MPCqJIU" \

Response

Body

{
  "story": {
    "name": "Story 1",
    "parent_id": 0,
    "group_id": "c14c1514-e2fa-42d1-9011-e466907ac39d",
    "alternates": [

    ],
    "created_at": "2018-11-10T15:33:29.396Z",
    "sort_by_date": null,
    "tag_list": [

    ],
    "updated_at": "2018-11-10T15:33:29.396Z",
    "published_at": null,
    "id": 1200,
    "uuid": "8ac32dab-8469-411a-8bf8-d17f2f0aa351",
    "is_folder": false,
    "content": {
      "component": "root",
      "body": [

      ],
      "_uid": "7a4834ff-5322-476d-85cc-f7f8503357ba"
    },
    "published": false,
    "slug": "da55c959-0ab2-4c8f-aedd-f8c6fa666a7c",
    "path": "/v1/spaces/687/stories",
    "full_slug": "da55c959-0ab2-4c8f-aedd-f8c6fa666a7c",
    "default_root": null,
    "disble_fe_editor": false,
    "parent": null,
    "is_startpage": false,
    "unpublished_changes": null,
    "meta_data": null,
    "imported_at": null,
    "preview_token": {
      "token": "",
      "timestamp": "1541864009"
    },
    "pinned": false,
    "breadcrumbs": [

    ],
    "publish_at": null,
    "expire_at": null,
    "first_published_at": null,
    "last_author": {
      "id": 1133,
      "userid": "jacques@heathcote.biz"
    }
  }
}

Deleting a story

Endpoint

DELETE /v1/spaces/:space_id/stories/:id

Request

cURL

curl "https://api.storyblok.com/v1/spaces/702/stories/1232" -d '' -X DELETE \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTc4LCJ0aW1lc3RhbXAiOjE1NDI0Njg4MTN9.BBPLvddc6NBusnH9rpKG7tEfFRxTVzINVK3vQo_cDOA" \

Response

Body

{
  "story": {
    "name": "Home",
    "parent_id": 0,
    "group_id": "0925708d-c222-432c-894d-0696ee7c9a43",
    "alternates": [

    ],
    "created_at": "2018-11-10T15:33:33.078Z",
    "sort_by_date": null,
    "tag_list": [

    ],
    "updated_at": "2018-11-10T15:33:33.078Z",
    "published_at": null,
    "id": 1232,
    "uuid": "66891bce-4dcc-45a3-9ce1-61d3533a40fd",
    "is_folder": false,
    "content": {
      "_uid": "xyz",
      "body": [
        {
          "_uid": "a9e16ab8-887f-4001-9548-313a09daeb2a",
          "text": "test1",
          "component": "headline"
        },
        {
          "_uid": "89a3cd23-8fd1-4ddc-abfe-a6396d012d14",
          "text": "test2",
          "component": "headline"
        }
      ],
      "component": "root"
    },
    "published": false,
    "slug": "home",
    "path": null,
    "full_slug": "home",
    "default_root": null,
    "disble_fe_editor": false,
    "parent": null,
    "is_startpage": false,
    "unpublished_changes": null,
    "meta_data": null,
    "imported_at": null,
    "preview_token": {
      "token": "",
      "timestamp": "1541864013"
    },
    "pinned": false,
    "breadcrumbs": [

    ],
    "publish_at": null,
    "expire_at": null,
    "first_published_at": null,
    "last_author": null
  }
}

Updating a story

Endpoint

PUT /v1/spaces/:space_id/stories/:id

Parameters

Name Description
force_update If '1' it will overwrite a locked story
publish If '1' the story will be published immediately after creating
story[name] required Name of the story
story[slug] required Slug to be used to receive the story from the api
story[content] JSON tree of the content
story[disble_fe_editor] Whether to disable the visual editor
story[default_root] Default root component. (Required if a folder story)
story[is_folder] Whether the story acts as a folder
story[group_id] Group ID. For example to make linkages between language versions
story[path] Url path the editor is opening the story
story[is_startpage] Whether the story is a startpage for this folder
story[parent_id] Id of the parent folder
story[sort_by_date] Sort by date in the format YYYY-MM-DD
story[first_published_at] First published date in the format YYYY-MM-DD HH:mm:ss
story[meta_data] Key value pairs to add meta data that is not setting the story status to unpublished changes. Example: User ratings.
story[pinned] To pin the story in the toolbar

Request

cURL

curl "https://api.storyblok.com/v1/spaces/688/stories/1202" -d '{"story":{"name":"Story 1","content":{"component":"root","body":[]},"path":"/v1/spaces/688/stories/1202"}}' -X PUT \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTM2LCJ0aW1lc3RhbXAiOjE1NDI0Njg4MDl9.q6sTX7pEJbosWgDaeJy8PKftsVsWSsqMlnjGveWQzH4" \

Response

Body

{
  "story": {
    "name": "Story 1",
    "parent_id": 0,
    "group_id": "3702f7df-7b9e-4497-83c6-d67781c7ac39",
    "alternates": [

    ],
    "created_at": "2018-11-10T15:33:29.574Z",
    "sort_by_date": null,
    "tag_list": [

    ],
    "updated_at": "2018-11-10T15:33:29.642Z",
    "published_at": null,
    "id": 1202,
    "uuid": "b1fa095b-4d26-4489-ae58-6adaf30e82b4",
    "is_folder": false,
    "content": {
      "component": "root",
      "body": [

      ],
      "_uid": "6ec00997-1d86-4f4d-8fd5-c09bab61535b"
    },
    "published": false,
    "slug": "home",
    "path": "/v1/spaces/688/stories/1202",
    "full_slug": "home",
    "default_root": null,
    "disble_fe_editor": false,
    "parent": null,
    "is_startpage": false,
    "unpublished_changes": true,
    "meta_data": null,
    "imported_at": null,
    "preview_token": {
      "token": "",
      "timestamp": "1541864009"
    },
    "pinned": false,
    "breadcrumbs": [

    ],
    "publish_at": null,
    "expire_at": null,
    "first_published_at": null,
    "last_author": {
      "id": 1136,
      "userid": "dayton_balistreri@bednar.com"
    }
  }
}

Export a story as JSON

ResourceInformation
Endpointhttps://mapi.storyblok.com/v1/spaces/:space_id/stories/:id/export.json
MethodGET
HeaderAuthorization:YOUR_MANAGEMENT_TOKEN

Export a story as XML

ResourceInformation
Endpointhttps://mapi.storyblok.com/v1/spaces/:space_id/stories/:id/export.xml
MethodGET
HeaderAuthorization:YOUR_MANAGEMENT_TOKEN

Import a story as JSON

ResourceInformation
Endpointhttps://mapi.storyblok.com/v1/spaces/:space_id/stories/:id/import.json
MethodPUT
HeaderAuthorization:YOUR_MANAGEMENT_TOKEN
Body{"data":"{ \"a9e16ab8-887f-4001-9548-313a09daeb2a:headline:text\":\"translated1\", \"89a3cd23-8fd1-4ddc-abfe-a6396d012d14:headline:text\":\"translated2\", \"page\":\"285\"}"}

Import a story as XML

ResourceInformation
Endpointhttps://mapi.storyblok.com/v1/spaces/:space_id/stories/:id/import.xml
MethodPUT
HeaderAuthorization:YOUR_MANAGEMENT_TOKEN
Body{"data":"<?xml version=\"1.0\" encoding=\"UTF-8\"?><page filename=\"home\" url=\"home\" id=\"283\"> <name>Home</name> <tags><tag id=\"a9e16ab8-887f-4001-9548-313a09daeb2a:headline:text\" type=\"STRING\"><text><![CDATA[translated1]]></text></tag><tag id=\"89a3cd23-8fd1-4ddc-abfe-a6396d012d14:headline:text\" type=\"STRING\"><text><![CDATA[translated2]]></text></tag> </tags></page>"}

Documentation