<!-- BusyBot node reference — https://busybot.net/tools/storyblok/ -->

> Node: Storyblok (`storyblok`) · Action · v1
> Category: Data & Storage · Credentials: Storyblok Content API (`storyblokContentApi`), Storyblok Management API (`storyblokManagementApi`)
> Updated: 2026-08-16

# Storyblok

> Manage stories in the Storyblok headless CMS

## Overview

Storyblok is a headless CMS that offers two different APIs: a Content Delivery API (read-only and CDN-cached) and a Management API (full CRUD and publishing). This tool reads stories through the Content API and manages them — get, list, delete, publish, unpublish — through the Management API. Stories are the core content unit in Storyblok, each one a structured tree of components.

**Category:** Data & Storage  
**Tool Name:** `storyblok`  
**Version:** 1

**Appearance:** Icon: `si-storyblok` | Color: `#09b3af`

## Node Type

**Action** — processes input items and produces output

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool requires **Storyblok Content API** or **Storyblok Management API** credentials. The Source parameter decides which one the node uses: Content API operations authenticate with the Content API credential, Management API operations with the Management API credential. Configure both if a workflow mixes the two.

See the [Credentials Guide](https://busybot.net/credentials/) for setup instructions.

### Resources

| Resource | Value |
|----------|-------|
| Story | `story` |

Both sources expose the same single resource — `story` — so Source and Operation are what you actually choose.

### Operations

| Source | Operation | Value | Description |
|--------|-----------|-------|-------------|
| Content API | Get | `get` | Get a story |
| Content API | Get Many | `getAll` | Get many stories |
| Management API | Delete | `delete` | Delete a story |
| Management API | Get | `get` | Get a story |
| Management API | Get Many | `getAll` | Get many stories |
| Management API | Publish | `publish` | Publish a story |
| Management API | Unpublish | `unpublish` | Unpublish a story |

### Parameters

The Operation list changes with Source, so the subsections below are grouped by Source and then by operation. Source itself, and Max Concurrency, are always visible — see All Operations.

#### Content API — Story: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Identifier | `string` | Yes | — | The numeric ID or full slug of the story to retrieve. Supports expressions like {{ $json.slug }}. _(shown when Source is `contentApi`)_ |

#### Content API — Story: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. _(shown when Source is `contentApi`)_ |
| Limit | `number` | No | `50` | Max number of results to return. _(shown when Source is `contentApi` and Return All is `false`)_ |
| Filters | `collection` | No | `{}` | Optional filters for listing stories. _(shown when Source is `contentApi`)_ |
| — Starts With | `string` | No | — | Filter stories by slug prefix (e.g. "blog/" to get all blog posts). |

#### Management API — Story: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Space ID | `string` | Yes | — | Numeric ID of the Storyblok space. Find in Storyblok dashboard: Settings > General > Space ID. _(shown when Source is `managementApi`)_ |
| Story ID | `string` | Yes | — | Numeric ID of the story. Supports expressions like {{ $json.storyId }}. _(shown when Source is `managementApi`)_ |

#### Management API — Story: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Space ID | `string` | Yes | — | Numeric ID of the Storyblok space. Find in Storyblok dashboard: Settings > General > Space ID. _(shown when Source is `managementApi`)_ |
| Story ID | `string` | Yes | — | Numeric ID of the story. Supports expressions like {{ $json.storyId }}. _(shown when Source is `managementApi`)_ |

#### Management API — Story: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Space ID | `string` | Yes | — | Numeric ID of the Storyblok space. Find in Storyblok dashboard: Settings > General > Space ID. _(shown when Source is `managementApi`)_ |
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. _(shown when Source is `managementApi`)_ |
| Limit | `number` | No | `50` | Max number of results to return. _(shown when Source is `managementApi` and Return All is `false`)_ |
| Filters | `collection` | No | `{}` | Optional filters for listing stories. _(shown when Source is `managementApi`)_ |
| — Starts With | `string` | No | — | Filter stories by slug prefix (e.g. "blog/" to get all blog posts). |

#### Management API — Story: Publish

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Space ID | `string` | Yes | — | Numeric ID of the Storyblok space. Find in Storyblok dashboard: Settings > General > Space ID. _(shown when Source is `managementApi`)_ |
| Story ID | `string` | Yes | — | Numeric ID of the story to publish. Supports expressions like {{ $json.storyId }}. _(shown when Source is `managementApi`)_ |
| Options | `collection` | No | `{}` | Additional publish options. _(shown when Source is `managementApi`)_ |
| — Release ID | `string` | No | — | Numeric ID of a release to publish the story into. |
| — Language | `string` | No | — | Language code to publish the story individually (must be enabled in the space settings). |

#### Management API — Story: Unpublish

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Space ID | `string` | Yes | — | Numeric ID of the Storyblok space. Find in Storyblok dashboard: Settings > General > Space ID. _(shown when Source is `managementApi`)_ |
| Story ID | `string` | Yes | — | Numeric ID of the story to unpublish. Supports expressions like {{ $json.storyId }}. _(shown when Source is `managementApi`)_ |

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Source | `options` | No | `contentApi` | Pick where your data comes from: Content Delivery API (read-only, CDN-cached) or Management API (full CRUD). |
| | | | | Options: `contentApi`, `managementApi` |
| Max Concurrency | `number` | No | `3` | Maximum number of items to process concurrently. Storyblok Management API has low rate limits (~3 req/s), so keep this low for Management API operations. |

## Output Data

The story's fields are merged onto the incoming item's JSON at the top level — there is no wrapper property, and fields already on the item survive unless the story overwrites them by name. Binary data on the input item is forwarded unchanged.

`Get`, `Delete`, `Publish` and `Unpublish` each produce exactly one output item per input item. `Get Many` fans out: one output item per story returned, so a listing of 200 stories turns one input item into 200 output items. A `Get Many` that matches nothing is the exception worth planning for — it emits the incoming item once, unchanged, rather than emitting nothing, so downstream nodes see an item with no story fields on it.

| Source | Operation | Output items per input item | Item JSON |
|--------|-----------|-----------------------------|-----------|
| Content API | `get` | 1 | The story, merged onto the item |
| Content API | `getAll` | one per story (the unchanged item when nothing matches) | One story per item, merged onto the item |
| Management API | `delete` | 1 | The deleted story as the API returned it; if the response carries no story, the raw response body instead |
| Management API | `get` | 1 | The story, merged onto the item |
| Management API | `getAll` | one per story (the unchanged item when nothing matches) | One story per item, merged onto the item |
| Management API | `publish` | 1 | The story in its published state |
| Management API | `unpublish` | 1 | The story in its unpublished state |

Reference fields downstream by expression, e.g. `{{ $json.name }}`, `{{ $json.full_slug }}` or `{{ $json.content.body }}`.

## Usage Examples

- Get a story by slug from Storyblok Content API
- List all stories in a Storyblok space
- Publish a story via the Management API
- Delete a story from a Storyblok space

## Example Configuration

Read a single published story by its full slug:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "contentApi",
    "resource": "story",
    "operation": "get",
    "identifier": "blog/my-article"
  }
}
```

Read a story whose ID arrives from an upstream node:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "contentApi",
    "resource": "story",
    "operation": "get",
    "identifier": "{{ $json.storyId }}"
  }
}
```

List the first 10 blog posts through the CDN:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "contentApi",
    "resource": "story",
    "operation": "getAll",
    "returnAll": false,
    "limit": 10,
    "filters": {
      "starts_with": "blog/"
    }
  }
}
```

Page through every story in the space, one item per story:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "contentApi",
    "resource": "story",
    "operation": "getAll",
    "returnAll": true
  }
}
```

Fetch the editable version of a story through the Management API:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "managementApi",
    "resource": "story",
    "operation": "get",
    "space": "67890",
    "storyId": "12345"
  }
}
```

List every product story in a space, keeping concurrency low for the Management API:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "managementApi",
    "maxConcurrency": 1,
    "resource": "story",
    "operation": "getAll",
    "space": "67890",
    "returnAll": true,
    "filters": {
      "starts_with": "products/"
    }
  }
}
```

Publish a single language of a story as part of a release:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "managementApi",
    "maxConcurrency": 2,
    "resource": "story",
    "operation": "publish",
    "space": "67890",
    "storyId": "{{ $json.storyId }}",
    "options": {
      "releaseId": "98765",
      "language": "en"
    }
  }
}
```

Take a story offline:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "managementApi",
    "resource": "story",
    "operation": "unpublish",
    "space": "67890",
    "storyId": "12345"
  }
}
```

Delete a story permanently:

```json
{
  "type": "storyblok",
  "parameters": {
    "source": "managementApi",
    "resource": "story",
    "operation": "delete",
    "space": "67890",
    "storyId": "12345"
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Read and manage stories in Storyblok headless CMS; use Content API for read-only access or Management API for full CRUD and publishing.

### Choosing a Source

- **Content API** is the read path your published site would use: CDN-cached, fast, and limited to `get` and `getAll`. It needs no space ID because the token you authenticate with already belongs to one space.
- **Management API** is the admin path: it reaches drafts, deletes, and the publish/unpublish endpoints, and every operation needs the numeric Space ID. It is rate-limited far more tightly, which is why Max Concurrency defaults to 3 — raise it only if you know your plan allows it.

### Notes

- **Identifier accepts either form.** On the Content API you can pass the numeric ID or the full slug (`blog/my-article`). Management API operations take the numeric Story ID only.
- **Return All ignores Limit** and keeps requesting pages of 100 until the space runs out of stories. On a large space that is a lot of requests against a rate-limited API; use a Limit while you build.
- **Starts With matches the slug prefix**, including folders — `blog/` returns everything filed under the blog folder, `blog` would also match `blog-archive/…`.
- **Publish is idempotent from the workflow's point of view.** Publishing an already-published story succeeds and returns the story; use the returned fields rather than assuming a state change happened.
- **Language must already be enabled** on the space before publishing a single language, otherwise the API rejects the request and the item fails.
- **Space ID and Story ID accept expressions**, so a single node can walk a list of stories produced upstream.