Was this page helpful?

Webhooks

Webhooks are HTTP callbacks which can be used to send notifications when data in Contentful is changed, allowing external systems to react to changes to do things such as trigger a website rebuild or send a notification to a chat application.

Content Events

Webhooks from these core entities are most commonly used to monitor when the state of any content from your space has been edited or updated.

Type / Action create save auto_save archive unarchive publish unpublish delete complete
ContentType Yes Yes No No No Yes Yes Yes No
Entry Yes Yes Yes Yes Yes Yes Yes Yes No
Asset Yes Yes Yes Yes Yes Yes Yes Yes No
Task Yes Yes No No No No No Yes No
Comment Yes No No No No No No Yes No
Release Yes Yes No Yes Yes No No Yes No
Workflow Yes Yes No No No No No No No
TemplateInstallation No No No No No No No No Yes

Common use cases for content event webhooks include:

  • running a test suite on a CI service when the content model of a development environment was changed
  • deploying a production build when content was published or un-published
  • deploying a preview build when the draft state of content has changed
  • re-building a search index when content was updated
  • feeding assets into an image detection service when they are uploaded
  • trigger email or chat authentication notifications due to editing activity
  • communicating creation and updates on tasks to the right stakeholders in real time

Other API Events

This section covers other types and their available actions.

Type / Action create save execute delete
ReleaseAction Yes No Yes No
ScheduledAction Yes Yes Yes Yes
BulkAction Yes No Yes No

NOTE: The webhook will be called immediately after the action has occurred.

Environment aliases and webhooks

Webhooks can be triggered for an environment alias using the filters property of a webhook just like environments. Webhooks only trigger for a given environment alias if it is used via that alias. Example: for a webhook set to trigger on the master environment alias only

  • Sending a PUT spaces/<space-id>/entries/my-blog-post would trigger the webhook

  • Sending a PUT spaces/<space-id>/environments/master/entries/my-blog-post would trigger the webhook

  • Sending a PUT spaces/<space-id>/environments/environment-to-serve/entries/my-blog-post would not trigger the webhook

Please refer to the webhooks reference for more details.

You can also set up webhooks to fire on environment alias events. For example, when an alias is created, updated or deleted.

Filtering of webhooks

Sometimes it is necessary to filter webhooks based on the properties of the entity that triggered the webhook. The most common examples are:

  • filter webhooks by environment ID (e.g. only trigger the pre-release test suite on a CI service for the environment with ID staging)
  • filter webhooks by entity ID (e.g. only trigger for a specific entry, asset or content type ID)
  • filter webhooks by content type ID (e.g. only trigger for entries of a specific content type ID)
Note: If a filter is evaluating a property that is not present on the entity, it will evaluate to false and not trigger the webhook. E.g. a webhook for topics Entry.publish and Asset.publish filters on a specific content type ID. As assets don't have a content type, all webhooks which are triggered by Asset.publish will be muted by the filter.

Create and configure a webhook

With the web app

In the top navigation bar, open SettingsWebhooks. Click Add webhook, configure the remote host and click Save.

Creating a new webhook

You can configure the specific events that trigger a webhook at the bottom of the screen.

Configure triggering events

With the API

Create a webhook by sending the settings for the webhook in a request body with your API call, for example, the following the http request:

curl -X POST "https://api.contentful.com/spaces/<SPACE_ID>/webhook_definitions"
  -d '{"url": "<URL>", "name": "foo", "topics": ["*.*"], , "filters": []}'
  -H 'Authorization: Bearer <API_KEY>'
  -H 'Content-Type: application/vnd.contentful.management.v1+json'

This webhook request will create a new webhook url in the specified space with a url, name, it will trigger for all topics and will not apply any filtering constraints.

Topics

When creating a webhook you have to explicitly specify for which changes on your content (topics) you want your webhook called.

For example, your webhook could be called when:

  • Any content (of any type) is published.
  • Assets are deleted.

These filters have to be translated into a list of [Type].[Action] pairs, [*.publish, Asset.delete, Entry.*], and included in the payload that defines the webhook.

* is a wildcard character that can be used in place of any action or type. The combination *.* is also valid and means that your webhook is subscribed to all actions across all types.

Note: Using * allows your webhook to be called for future actions or types that didn't exist when the webhook was created or updated. Find more details on creating a webhook with the API in our reference docs.

Headers

By default, all webhooks will contain the following headers

Header Name Value
X-Contentful-Topic ContentManagement.[Type].[Action]
X-Contentful-Webhook-Name Webhook's name
Content-Type application/vnd.contentful.management.v1+json

Additionally, extra headers may be sent to provide extra context, such as which scheduled action or bulk action triggered the action. A summary of these headers can be found in the webhooks section in the reference documentation of the Content Management API.

Filters

The webhook definition holds a filters property. Filtering is a second step after defining the topics. Typical use cases for filtering are enabling a webhook only for a specific environment ID or entry ID. Without a filter, a webhook with the topic Entry.publish is triggering for all entries in the master environment of a space. By applying a filter we could make the webhook only trigger for specific entry IDs within a specific environment.

A filter is defined by adding one or multiple parameter constraints to the webhook definition. The constraints consist of:

A property of the entity to evaluate:

  • sys.id
  • sys.environment.sys.id
  • sys.contentType.sys.id (for entries)

An operator / negation of an operator:

  • equals
  • in
  • regex

An argument for selected operator:

  • string value (e.g. "myEntryId") for equals
  • array of strings (e.g. ["idOne", "idTwo"]) for in
  • definition of a pattern (e.g. {"pattern": "^ci-.+$"} for regexp

So for example filtering a webhook to only trigger for two specific environments of ID master or development, the constraint would look like:

{
  ...,
  "filters": [
    {
      "in": [
        {
          "doc": "sys.environment.sys.id"
        },
        [
          "master",
          "development"
        ]
      ]
    }
  ]
}

Multiple constraints are connected with logical AND. Let's narrow the above's filter further down so it only triggers for an entry of ID foo in environments with ID master or development:

{
  ...,
  "filters": [
    {
      "in": [
        {
          "doc": "sys.environment.sys.id"
        },
        [
          "master",
          "development"
        ]
      ]
    },
    {
      "equals": [
        {
          "doc": "sys.id"
        },
        "foo"
      ]
    }
  ]
}

The last example uses a regular expression to match all environments that have an ID which uses a common prefix of ci- followed by 3-5 lowercase characters (e.g. ci-foo, ci-bar but not ci-foobar:

{
  ...,
  "filters": [
    {
      "regexp": [
        {
          "doc": "sys.environment.sys.id"
        },
        {
          "pattern": "^ci-[a-z]{3,5}$"
        }
      ]
    }
  ]
}

Please note that filtering is done on the literal value of the path. It means that if you access your content through multiple environment aliases, you need to include all of them when attempting to filter based on sys.environment.sys.id.

For a full reference on how filters are defined please refer to the webhooks section in the reference documentation of the Content Management API.

Disabling a webhook

Sometimes you may need to disable a webhook. Perhaps the web service that should receive webhooks service is still under development, or perhaps you need want to avoid receiving webhook calls whilst you perform a data migraiton in Contentful.

The webhook configuration UI provides a toggle that can be used to disable or enable a webhook. It is also possible to disable a webhook through the api. For more details about webhooks see the Webhook API guide.

List webhooks in a space

With the web app

The Webhooks overview screen shows a list of the most recent webhook calls made, their status, possible errors, and the target URL (a Slack url in the below example).

Overview of webhooks

With the API

To list all webhooks endpoint in a space, use the following sample code:

curl -X GET "https://api.contentful.com/spaces/<SPACE_ID>/webhook_definitions"
-H "Authorization: Bearer <API_KEY>"
-H "Content-Type: application/vnd.contentful.management.v1+json"

Find more details on listing the webhooks in a space with the API in our reference docs.

Activity log of a call

With the web app

Click the View details link of any webhook events in the overview screen to get a detailed activity log, including the JSON and remote server response.

Activity log for webhooks

Detailed activity log of a webhook

Note: A maximum of 500 log entries are stored for each webhook. When this number is reached, the oldest entry is automatically deleted.

With the API

The following endpoint will return the status of recent calls made by a webhook and any errors.

curl -X GET "https://api.contentful.com/spaces/<SPACE_ID>/webhooks/<WEBHOOK_ID>/calls"
-H "Authorization: Bearer <API_KEY>"
-H "Content-Type: application/vnd.contentful.management.v1+json"

Find more details on getting the activity log of a webhook with the API in our reference docs.

save and auto_save webhooks

The Contentful web application automatically saves changes in all documents you are working on. Contentful considers documents edited in the last 5 seconds as active and uses that information to call the webhook integrations you have configured.

If you edit an entry in the web app for one minute, and you have a webhook configured to be called for auto_save actions, the defined webhook will be sent 12 times (60 seconds divided by 5 seconds).

When you call the sdk.entry.save() method provided by the App SDK an auto_save webhook is sent.

If you update an entry or asset via the Content Management API or an App the save webhook is sent.

Local testing

For local testing we recommend to use webhook.site to inspect the sent webhooks or ngrok to build webhook consumers on your developer machine. ngrok also provides a guide on how to use ngrok to integrate your localhost app with Contentful by using Webhooks.

Customizing webhook calls

By default every webhook call:

  • uses the HTTP POST request method
  • has the Content-Type header set to application/vnd.contentful.management.v1+json
  • sends a predefined body depending on the triggering event

If you want to change any of the aforementioned webhook properties you can use a mechanism called "webhook transformation". Navigate to the CMA reference for more details. All customizable properties can be set with both the API and the web app.

Action Reference

Release

Releases are containers for multiple entries and assets that can have an action taken upon all referenced content. Note that release webhooks are called when the release entity itself is changed or deleted, not when an action is taken (see release actions)

  • create: emitted after the release has been successfully created
  • save: emitted after the release has been successfully changed
  • delete: emitted after a release has been deleted
  • archive: emitted after a release has been archived
  • unarchive: emitted after a release has been unarchived

Release webhooks can be used for triggering validation flows when entities are added or removed from a release, or tracking new or deleted releases

Learn more about releases in the releases reference

Release actions

Release actions are a specific attempt to take an action on a release, such as publish or unpublish.

  • create: emitted after the release action has been created, but may not have started yet
  • execute: emitted after the release action has been executed, regardless of outcome. The entity emitted will show the resulting status

Release action webhooks can be used for delaying a build or checking the outcome of a release action once it has been taken, including validation errors received during execution.

Learn more about release actions in the releases reference

Bulk actions

Bulk actions are one-time entities containing a collection of entries and assets and an action to apply, such as publishing a Compose page or publishing a collection of entries and assets from the reference tree.

  • create: emitted after the bulk action has been successfully created, but may not have started yet
  • execute: emitted after the bulk action has been executed, regardless of outcome. The payload emitted will include the resulting status

Bulk action webhooks can be used for delaying a build or checking the outcome of a bulk action once it has been taken, including validation errors received during execution.

Learn more about bulk actions in the bulk actions reference

Scheduled actions

Scheduled actions are actions that are taken on behalf of a user at a future date.

  • create: emitted after the scheduled action has been created, but may not have started yet
  • save: emitted after the scheduled action has been successfully changed
  • execute: emitted after the scheduled action has been executed, regardless of outcome. The entity emitted will show the resulting status
  • delete: emitted after a scheduled action has been deleted

Scheduled action webhooks can be used for keeping external systems apprised of changes to upcoming type of events or for emitting chatbot messages in the case of a failed scheduled action execution.

Learn more about scheduled actions in the scheduled actions reference

Next steps

Not what you’re looking for? Try our FAQ.