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

> Node: Strapi (`strapi`) · Action · v1
> Category: Data & Storage · Credentials: Strapi (Username & Password) (`strapiApi`), Strapi API Token (`strapiTokenApi`)
> Updated: 2026-08-16

# Strapi

> CRUD operations for Strapi headless CMS content entries

## Overview

Strapi is a self-hosted, open-source headless content management system. This tool creates, reads, updates and deletes content entries in any content type you have defined. It supports both the Strapi v3 and v4 APIs, which differ in URL structure, request body format, query parameter conventions and response shape; the version you are talking to — along with your instance URL — comes from the credential you select, so the same node configuration works against either. Content types are your own, and you name them as a string.

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

**Appearance:** Icon: `si-strapi` | Color: `#4945FF`

## Node Type

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

## Input / Output

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

## Credentials

This tool requires **Strapi (Username & Password)** or **Strapi API Token** credentials — configure whichever matches your instance, and use the Authentication parameter to pick the one this node uses. Username & Password exchanges your login for a short-lived token each run; API Token uses a token you generated in Strapi beforehand.

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

### Resources

| Resource | Value |
|----------|-------|
| Entry | `entry` |

### Operations

| Operation | Value | Description |
|-----------|-------|-------------|
| Create | `create` | Create an entry |
| Delete | `delete` | Delete an entry |
| Get | `get` | Get an entry |
| Get Many | `getAll` | Get many entries |
| Update | `update` | Update an entry |

### Parameters

#### Entry: Create

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Content Type | `string` | Yes | — | Name of the content type (e.g. "articles", "products"). This is the plural API name of your Strapi content type. |
| Columns | `string` | No | — | Comma-separated list of field names from the input item to include in the request body. Only listed fields will be sent to Strapi. |

#### Entry: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Content Type | `string` | Yes | — | Name of the content type. |
| Entry ID | `string` | Yes | — | The ID of the entry to delete. Supports expressions like {{ $json.articleId }}. |

#### Entry: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Content Type | `string` | Yes | — | Name of the content type. |
| Entry ID | `string` | Yes | — | The ID of the entry to get. Supports expressions like {{ $json.articleId }}. |

#### Entry: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Content Type | `string` | Yes | — | Name of the content type. |
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `50` | Max number of results to return. _(shown when Return All is `false`)_ |
| Options | `collection` | No | `{}` | Extra query options applied to the listing. |
| — Publication State | `options` | No | — | Only select entries matching the publication state provided. |
| | | | | Options: `live` (published entries only), `preview` (drafts as well as published entries) |
| — Sort Fields | `string` | No | — | Comma-separated sort fields. Each field optionally followed by ":asc" or ":desc". Example: "name:asc,createdAt:desc". |
| — Where (JSON) | `string` | No | — | JSON filter query. For Strapi v3 uses _where syntax. For Strapi v4 uses filters syntax. Must be valid JSON. |

#### Entry: Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Content Type | `string` | Yes | — | Name of the content type. |
| Update Key | `string` | Yes | `id` | Name of the property in the input data that contains the entry ID. Normally "id". |
| Columns | `string` | No | — | Comma-separated list of field names from the input item to include in the update request body. |

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Authentication | `options` | No | `password` | Authentication method to use. Username & Password obtains a JWT at runtime; API Token uses a pre-generated token. |
| | | | | Options: `password`, `token` |
| Max Concurrency | `number` | No | `10` | Maximum number of items to process concurrently. |

## Output Data

The entry returned by Strapi **is** the output item's JSON — the result is not nested under a property, and the incoming item's own fields are not carried through. Binary data on the input item is forwarded unchanged.

`Create`, `Delete`, `Get` and `Update` each produce exactly one output item per input item. `Get Many` fans out: one output item per entry returned, so a listing that matches 200 entries turns one input item into 200 output items — and a listing that matches nothing produces no output items at all for that input item.

| Operation | Output items per input item | Item JSON |
|-----------|-----------------------------|-----------|
| `create` | 1 | The created entry, exactly as the API returned it. On v4 that is the `{ data, meta }` envelope, so the entry itself is under `data`. |
| `delete` | 1 | The deleted entry, exactly as the API returned it. On v4 that is the `{ data, meta }` envelope. |
| `get` | 1 | The entry. On v4 the `data` envelope is unwrapped for you. |
| `getAll` | one per entry returned (none when nothing matches) | One entry per item. On v4 each item is an entry out of `data`. |
| `update` | 1 | The updated entry. On v4 the `data` envelope is unwrapped for you. |

Reference fields downstream by expression, e.g. `{{ $json.id }}` or `{{ $json.attributes.title }}` on v4.

## Usage Examples

- Create a new blog post entry in Strapi
- Get all products from Strapi with filtering
- Update an article entry in Strapi CMS
- Delete a content entry from Strapi by ID

## Example Configuration

Create an article from the incoming item, sending only three of its fields:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "token",
    "resource": "entry",
    "operation": "create",
    "contentType": "articles",
    "columns": "title,content,publishedAt"
  }
}
```

Fetch a single entry by ID:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "password",
    "resource": "entry",
    "operation": "get",
    "contentType": "articles",
    "entryId": "123"
  }
}
```

List published articles, newest first, capped at 25:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "token",
    "resource": "entry",
    "operation": "getAll",
    "contentType": "articles",
    "returnAll": false,
    "limit": 25,
    "options": {
      "publicationState": "live",
      "sort": "createdAt:desc"
    }
  }
}
```

Page through every matching product, filtering with a JSON query:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "token",
    "resource": "entry",
    "operation": "getAll",
    "contentType": "products",
    "returnAll": true,
    "options": {
      "publicationState": "live",
      "sort": "price:asc,name:asc",
      "where": "{\"category\":\"electronics\"}"
    }
  }
}
```

Update the entry whose ID is on the incoming item under `id`:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "token",
    "resource": "entry",
    "operation": "update",
    "contentType": "articles",
    "updateKey": "id",
    "columns": "title,content"
  }
}
```

Delete an entry whose ID comes from an upstream node:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "password",
    "resource": "entry",
    "operation": "delete",
    "contentType": "articles",
    "entryId": "{{ $json.articleId }}"
  }
}
```

Push a batch of price changes, keeping the request rate modest:

```json
{
  "type": "strapi",
  "parameters": {
    "authentication": "token",
    "resource": "entry",
    "operation": "update",
    "contentType": "products",
    "updateKey": "id",
    "columns": "price,inventory",
    "maxConcurrency": 5
  }
}
```

### 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

Create, read, update, and delete content entries in a self-hosted Strapi headless CMS. Use when you need to manage content in Strapi v3 or v4 instances.

### Notes

- **The body comes from the item, not from the node.** `Create` and `Update` build the request body out of the incoming item's JSON, and Columns is the whitelist over those fields. Leave it empty and every field on the item is sent, which is rarely what you want when the item carries extra bookkeeping fields. On Strapi v4 the item is sent whole as the entry body regardless, so shape the item upstream — with an Edit Fields node — rather than relying on Columns to trim it.
- **Update needs the ID on the item.** The entry ID is read from the item property named by Update Key (`id` by default), not from a parameter. If that property is missing or empty the item fails with a clear error, so map it upstream.
- **Where (JSON) must parse as JSON.** A prose filter such as `title contains 'news'` is rejected before the request is sent. Write the filter as a JSON object — `_where` shape on v3, `filters` shape on v4.
- **Return All pages through everything.** With Return All on, the node keeps requesting pages until the API stops returning entries, and Limit is ignored. On a large content type that is a lot of requests and a lot of items; prefer a Limit while you are building the workflow.
- **Content Type is the plural API name** as Strapi exposes it in the URL (`articles`, not `Article`), and it accepts expressions, so one node can serve several types driven by upstream data.
- **Match the credential to the instance.** The API version and base URL live on the credential, so pointing a workflow at a different Strapi instance is a credential swap, not a node edit.