---
title: Webhooks
description: Discover Storyblok's documentation with comprehensive developer guides, user manuals, API references, and examples to help you get the most out of the headless CMS platform.
url: https://www.storyblok.com/docs/concepts/webhooks
---

# Webhooks

A webhook lets one application send information to another. In Storyblok, webhooks notify external services about events: story published, asset uploaded, user removed, discussion created, and many more.

This receiving service can than innitiate automated tasks, such as clearing caches or triggering build processes.

## Set up webhooks

To configure a webhook in Storyblok:

1.  In your space, open **Settings** → **Webhooks** and select **\+ New Webhook**.
2.  Enter the **Endpoint URL** that handles the payload.
3.  In [paid plans](https://www.storyblok.com/pricing), add a **Webhook secret** for verification.
4.  Select one or more events that trigger the webhook.

  

> [!NOTE]
> The receiving service must respond with a `2xx` status code and `content-type: application/json`.

## Webhook triggers and example payloads

Storyblok provides 28 triggers to choose from, covering events related to stories, assets, workflows, user management, data sources, discussions, experiments, and apps (Releases, Tasks, and Pipelines).

Each trigger provides a payload with matching properties:

-   **Universal fields:** all payloads include `text`, `action`, and `space_id` properties.
-   **Entity-specific fields:** each trigger also includes its own properties. For example, `story_id`, `asset_id`, `workflow_name`, `user_id`, `datasource_slug`, and so on.

The following triggers produce payloads that follow

### **Story**

| Event Name | Description |
| --- | --- |
| published | A story is published |
| unpublished | A story is unpublished |
| deleted | A story is deleted |
| moved | A story is moved |

### **Asset**

  

### **Workflow**

### **User management**

### **Data source**

| Event Name | Description |
| --- | --- |
| entries\_updated | A datasource entry is saved or added |
| datasource\_entry\_saved | A datasource entry is saved or added (legacy webhook) |

### **Discussion**

### Experiments

### **Releases**

### Tasks

### **Pipelines**

  
  

### **Asset**

| Event Name | Description |
| --- | --- |
| created | An asset is uploaded |
| replaced | An asset is replaced |
| deleted | An asset is deleted |
| restored | An asset is restored |

### **User management**

| Event Name | Description |
| --- | --- |
| added | A user is added to the space |
| removed | A user is removed from the space |
| roles\_updated | A user role is updated |

### **Workflow**

| Event Name | Description |
| --- | --- |
| stage.changed | The workflow stage of a story changed |
| workflow\_stage\_changed | The workflow stage of a story changed (legacy webhook) |

### **Discussion**

| Event Name | Description |
| --- | --- |
| created | A discussion is created |
| comment\_created | A comment added in the discussion |
| comment\_updated | A comment updated |
| comment\_deleted | A comment deleted |
| resolved | A discussion is resolved |

### **Pipeline**

> [!WARNING]
> To use pipeline webhooks, install the [Pipelines App](https://www.storyblok.com/apps/branches).

| Event Name | Description |
| --- | --- |
| deployed | A pipeline stage is deployed |
| branch\_deployed | A pipeline stage is deployed (legacy webhook) |

### **Releases**

> [!WARNING]
> To use release webhooks, install the [Releases App](https://www.storyblok.com/apps/releases_only).

| Event Name | Description |
| --- | --- |
| merged | A release is merged into the current released content |
| release\_merged | A release is merged into the current released content (legacy webhook) |

### Tasks

> [!WARNING]
> To use task webhooks, install the [Tasks App](https://www.storyblok.com/apps/tasks).

The Tasks App allows you to create automation tasks that trigger webhooks when clicking the **Execute** button. To configure a webhook, create a new task.

You can pass user inputs as `dialog_values`, which will be sent as the payload.

| Event Name | Description |
| --- | --- |
| task\_execution | Trigger a request from Storyblok |
| task\_execution | With user dialog: the payload contains additional data in dialog\_values |

Example payload

```json
{
    "task": {
        "id": 123,
        "name": "Trigger Webhook"
    },
    "text": "The user test@domain.com executed the task Trigger Webhook",
    "action": "task_execution",
    "space_id": 123,
    "dialog_values": {
        "name": "Test",
        "environment": "dev"
    }
}
```

# ALL PAYLOADS

# INTRO

-   **Universal fields:** all payloads share `text`, `action`, and `space_id` props
-   **Entity-specific props:** each trigger also includes its own props. For example, `story_id`, `asset_id`, `user_id`, `branch_id`, `release_id`, `datasource_slug`.

Example payload

```json
[
  {
    "trigger": "story.published",
    "payload": {
      "text": "The user joy.bringer@storyblok.com published the Story Home 2 (marketing-articles/home-2)\nhttps://app.storyblok.com/#/me/spaces/184738/stories/0/0/166888799188279",
      "action": "published",
      "space_id": 184738,
      "story_id": 166888799188279,
      "full_slug": "marketing-articles/home-2"
    }
  },
  {
    "trigger": "story.unpublished",
    "payload": {
      "text": "The user joy.bringer@storyblok.com unpublished the Story Home 2 (marketing-articles/home-2)\nhttps://app.storyblok.com/#/me/spaces/184738/stories/0/0/166888799188279",
      "action": "unpublished",
      "space_id": 184738,
      "story_id": 166888799188279,
      "full_slug": "marketing-articles/home-2"
    }
  },
  {
    "trigger": "story.deleted",
    "payload": {
      "text": "The user joy.bringer@storyblok.com deleted the Story 2 (2)\nhttps://app.storyblok.com/#/me/spaces/184738/stories/0/0/166887004517421",
      "action": "deleted",
      "space_id": 184738,
      "story_id": 166887004517421,
      "full_slug": "2"
    }
  },
  {
    "trigger": "story.moved",
    "payload": {
      "text": "The user joy.bringer@storyblok.com moved the Story Home 2 (marketing-articles/home-2)\nhttps://app.storyblok.com/#/me/spaces/184738/stories/0/0/166888799188279",
      "action": "moved",
      "space_id": 184738,
      "story_id": 166888799188279,
      "full_slug": "marketing-articles/home-2",
      "old_full_slug": "home-2"
    }
  },
  {
    "trigger": "datasource.entries_updated",
    "payload": {
      "text": "The datasource entry test has been saved.",
      "action": "entries_updated",
      "space_id": 184738,
      "datasource_slug": "background-color-options"
    }
  },
  {
    "trigger": "datasource.entries_deleted",
    "payload": {
      "text": "The datasource entry Test 1 has been deleted.",
      "action": "entries_deleted",
      "space_id": 184738,
      "datasource_slug": "test"
    }
  },
  {
    "trigger": "asset.created",
    "payload": {
      "text": "The user joy.bringer@storyblok.com created the Asset asdasdas.jpeg\nhttps://a.storyblok.com/f/184738/2048x1366/4a5ba99420/asdasdas.jpeg",
      "action": "created",
      "asset_id": 166889582905517,
      "space_id": 184738
    }
  },
  {
    "trigger": "asset.replaced",
    "payload": {
      "text": "The user joy.bringer@storyblok.com replaced the Asset asdasdas.jpeg\nhttps://a.storyblok.com/f/184738/2048x1366/4a5ba99420/asdasdas.jpeg",
      "action": "replaced",
      "asset_id": 166889582905517,
      "space_id": 184738
    }
  },
  {
    "trigger": "asset.deleted",
    "payload": {
      "text": "The user joy.bringer@storyblok.com deleted the Asset my-test-asset.webp\nhttps://a.storyblok.com/f/184738/ca28f3e327/my-test-asset.webp",
      "action": "deleted",
      "asset_id": 141684807612387,
      "space_id": 184738
    }
  },
  {
    "trigger": "asset.restored",
    "payload": {
      "text": "The user joy.bringer@storyblok.com restored the Asset my-test-asset.webp\nhttps://a.storyblok.com/f/184738/ca28f3e327/my-test-asset.webp",
      "action": "restored",
      "asset_id": 141684807612387,
      "space_id": 184738
    }
  },
  {
    "trigger": "user.added",
    "payload": {
      "text": "The user joy.bringer@storyblok.com was added by joy.bringer@storyblok.com",
      "action": "added",
      "user_id": 110860,
      "space_id": 184738
    }
  },
  {
    "trigger": "user.removed",
    "payload": {
      "text": "The user joy.bringer@storyblok.com was removed by joy.bringer@storyblok.com",
      "action": "removed",
      "user_id": 110860,
      "space_id": 184738
    }
  },
  {
    "trigger": "user.roles_updated",
    "payload": {
      "text": "The user joy.bringer@storyblok.com roles were updated by joy.bringer@storyblok.com",
      "action": "roles_updated",
      "user_id": 110860,
      "space_id": 184738
    }
  },
  {
    "trigger": "discussion.created",
    "payload": {
      "id": 166895941348171,
      "lang": "default",
      "text": "user joy.bringer@storyblok.com:Test test, Discussion created on Story: Home \nhttps://app.storyblok.com//#/me/spaces/184738/stories/0/0/153831606405117?discussionId=166895941348171",
      "title": "Body",
      "action": "created",
      "space_id": 184738,
      "story_id": 153831606405117,
      "block_uid": "a9e71780-2114-4860-8d0f-e72a726d627c",
      "component": "page",
      "fieldname": "body"
    }
  },
  {
    "trigger": "discussion.resolved",
    "payload": {
      "id": 166890710530888,
      "lang": "default",
      "text": "user joy.bringer@storyblok.com:hello, Discussion resolved on Story: Home \nhttps://app.storyblok.com//#/me/spaces/184738/stories/0/0/153831606405117?discussionId=166890710530888",
      "title": "Body",
      "action": "resolved",
      "space_id": 184738,
      "story_id": 153831606405117,
      "block_uid": "a9e71780-2114-4860-8d0f-e72a726d627c",
      "component": "page",
      "fieldname": "body"
    }
  },
  {
    "trigger": "discussion.comment_created",
    "payload": {
      "id": 166895941348171,
      "lang": "default",
      "text": "user joy.bringer@storyblok.com:test , Discussion comment_created on Story: Home \nhttps://app.storyblok.com//#/me/spaces/184738/stories/0/0/153831606405117?discussionId=166895941348171",
      "title": "Body",
      "action": "comment_created",
      "space_id": 184738,
      "story_id": 153831606405117,
      "block_uid": "a9e71780-2114-4860-8d0f-e72a726d627c",
      "component": "page",
      "fieldname": "body"
    }
  },
  {
    "trigger": "discussion.comment_deleted",
    "payload": {
      "id": 166894687697738,
      "lang": "default",
      "text": "user joy.bringer@storyblok.com:Hello 23213, Discussion comment_deleted on Story: Home \nhttps://app.storyblok.com//#/me/spaces/184738/stories/0/0/153831606405117?discussionId=166894687697738",
      "title": "Name Translatable",
      "action": "comment_deleted",
      "space_id": 184738,
      "story_id": 153831606405117,
      "block_uid": "226b329a-8330-4bce-8890-b879ebf3419e",
      "component": "feature",
      "fieldname": "name_translatable"
    }
  },
  {
    "trigger": "discussion.comment_updated",
    "payload": {
      "id": 166894687697738,
      "lang": "default",
      "text": "user joy.bringer@storyblok.com:Hello 23213, Discussion comment_updated on Story: Home \nhttps://app.storyblok.com//#/me/spaces/184738/stories/0/0/153831606405117?discussionId=166894687697738",
      "title": "Name Translatable",
      "action": "comment_updated",
      "space_id": 184738,
      "story_id": 153831606405117,
      "block_uid": "226b329a-8330-4bce-8890-b879ebf3419e",
      "component": "feature",
      "fieldname": "name_translatable"
    }
  },
  {
    "trigger": "stage.changed",
    "payload": {
      "text": "The workflow stage of story Home has been changed to Drafting.",
      "action": "stage.changed",
      "space_id": 184738,
      "story_id": 153831606405117,
      "workflow_name": "Default",
      "workflow_stage_name": "Drafting"
    }
  },
  {
    "trigger": "pipeline.deployed",
    "payload": {
      "text": "The branch Staging has been deployed.",
      "action": "deployed",
      "space_id": 184738,
      "branch_id": 101770473635025
    }
  },
  {
    "trigger": "release.merged",
    "payload": {
      "text": "The release Test has been merged.",
      "action": "merged",
      "space_id": 184738,
      "release_id": 166891358857247
    }
  },
  {
    "trigger": "experiment.created",
    "payload": {
      "text": "user joy.bringer@storyblok.com created the experiment A simple experiment",
      "action": "experiment.created",
      "status": "draft",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.started",
    "payload": {
      "text": "user joy.bringer@storyblok.com started the experiment A simple experiment",
      "action": "experiment.started",
      "status": "running",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.paused",
    "payload": {
      "text": "user joy.bringer@storyblok.com paused the experiment A simple experiment",
      "action": "experiment.paused",
      "status": "paused",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.resumed",
    "payload": {
      "text": "user joy.bringer@storyblok.com resumed the experiment A simple experiment",
      "action": "experiment.resumed",
      "status": "running",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.winner_selected",
    "payload": {
      "text": "user joy.bringer@storyblok.com selected a winner for the experiment A simple experiment",
      "action": "experiment.winner_selected",
      "status": "completed",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.completed",
    "payload": {
      "text": "user joy.bringer@storyblok.com completed the experiment A simple experiment",
      "action": "experiment.completed",
      "status": "completed",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  },
  {
    "trigger": "experiment.deleted",
    "payload": {
      "text": "user joy.bringer@storyblok.com deleted the experiment A simple experiment",
      "action": "experiment.deleted",
      "status": "completed",
      "space_id": 292476528754160,
      "experiment_id": 176070002766742
    }
  }
]
```

  

> [!NOTE]
> There’s no default option to add a webhook secret to verify task webhook payloads. However, you can pass a secret key via the user input dialog and verify it in your project's code.

## Secure a webhook

Protect your webhooks with two methods:

-   Verify webhook signature
-   Allow Storyblok static IP addresses

### Verify webhook signature

> [!NOTE]
> Refer to our [pricing plans](https://www.storyblok.com/pricing) to check if your account supports webhook secrets.

Ensuring your requests come only from trustworthy sources can help safeguard your applications. You can protect your webhooks by verifying they were triggered by Storyblok events. The sender of the webhook can be verified by validating the signature sent along with the payload and generated with a shared secret key (webhook secret).

Define Webhook secret

We recommend using a randomly generated string with at least 20 characters for your webhook secret. You can generate one using the following command:

```bash
openssl rand -hex 20
```

Once you save the secret, Storyblok includes a signature in every webhook request. The signature is sent in the `webhook-signature` header. If no secret is set, this header remains empty.

To verify webhook requests, your endpoint should check if the secret generated the correct `webhook-signature`. For a step-by-step guide, follow our tutorial: [**Securing Webhooks: Verifying Signatures in Different Technologies**](https://www.storyblok.com/tp/webhook-secret-with-different-technologies). It provides actual code examples to help you implement verification.

### Allow Storyblok static IP addresses

To protect your webhooks, allow access only from IPs on your allowlist. This prevents unauthorized third-party access to your webhooks.

> [!WARNING]
> Storyblok static IPs are not available in the China region.

Add the Storyblok static IPs for your space’s region to your allowlist:

|     |     |     |
| --- | --- | --- |
| **Space Region** | **Main IP** | **Fallback IP** |
| European Union (EU) | 3.121.25.244 | 35.159.255.4 |
| United States (US) | 44.206.118.25 | 3.231.44.46 |
| Canada (CA) | 15.157.6.14 | 35.183.66.204 |
| Australia (AP) | 13.238.72.230 | 52.63.91.95 |

> [!NOTE]
> Add both the Main IP and Fallback IP for your space region to your allowlist.

## Troubleshoot webhooks

To quickly identify issues with webhooks, you can use two effective strategies.

1.  Open **Settings** → **Webhooks**, and select **View logs** of the relevant webhook. The logs provide detailed information on each run, including its status, JSON response, and payload.
2.  Use an external service, such as [webhook.site](http://webhook.site/) or [RequestBin,](https://pipedream.com/requestbin) to test and inspect webhook request data in a controlled environment. These tools can help you analyze and debug webhook interactions more effectively.

## Errors

Webhooks don't retry on failure. Retrying could cause issues, as `Publish` and `Save` are single events. For long-running tasks, respond immediately (for example, `202` Accepted) to avoid timeouts after 120 seconds.

## Related resources

[Webhooks in the Management API](https://www.storyblok.com/docs/api/management/webhooks)

## Pagination

-   [Previous: Visual Editor](https://www.storyblok.com/docs/concepts/visual-editor)
