# Webhooks

## Webhooks

Webhooks provide real-time, event-driven communication within Umbraco. Seamlessly integrated, these lightweight, HTTP-based notifications empower you to trigger instant actions and synchronize data. With its different extension points, you can tailor these webhooks to fit a broad range of requirements.

### Getting Started

To work with Webhooks, you need to go to Webhooks within the Settings section:![Webhooks section](https://3872888104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgEH4FChbCn7eDDqREvdE%2Fuploads%2Fgit-blob-533780ac10147f4cd22f183bfae58882f10b6f10%2Fwebhook-section.png?alt=media)

From here we can create a webhook, by clicking the `Create webhook` button, which will take you to the Create webhook screen:

![Creating a webhook](https://3872888104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgEH4FChbCn7eDDqREvdE%2Fuploads%2Fgit-blob-cc440dea37ce25e6336b48ba415c77f96b2cd6ca%2Fcreate-webhook.png?alt=media)

### Url

The `Url` should be the endpoint you want the webhook to send a request to, whenever a given `Event` is fired.

### Events

Events are when a given action happens, by default there are 5 events you can choose from.

* Content Published - This event happens whenever some content gets published.
* Content Unpublished - This event happens whenever some content gets unpublished
* Content Deleted - This event happens whenever some content gets deleted.
* Media Deleted - This event happens whenever a media item is deleted.
* Media Saved - This event happens whenever a media item is saved.

### Content type

If you have selected a Content or Media event, you can specify your preferences. You can choose to trigger your webhook only for a given Document or Media type.

For example, if you have selected `Content Published` event. You can then specify that you only want the webhook to fire, when the content is of a given content type.

### Headers

You can specify custom headers, that will be sent with your request.

For example you could specify `Accept: application/json`, security headers, etc.

## Defaults

Umbraco webhooks have been configured with some defaults, such as default headers or some events that send a payload. In this section, we will take a look at those.

### Json payload

For example, the `Content Published` event will also send the given content that triggered the event. The json from is the same as the `Content Delivery Api`, an example of such a json object:

```json
{
  "Name": "Root",
  "CreateDate": "2023-12-11T12:02:38.9979314",
  "UpdateDate": "2023-12-11T12:02:38.9979314",
  "Route": {
    "Path": "/",
    "StartItem": {
      "Id": "c1922956-7855-4fa0-8f2c-7af149a92135",
      "Path": "root"
    }
  },
  "Id": "c1922956-7855-4fa0-8f2c-7af149a92135",
  "ContentType": "root",
  "Properties": {}
}
```

however, the `Content deleted` does not send the entire content as JSON, instead, it sends the `Id` of the content like so:

```json
{
  "Id": "c1922956-7855-4fa0-8f2c-7af149a92135"
}
```

### Headers

By default, webhook requests will include 3 headers

* `user-agent: Umbraco-Cms/{version}`, where version is the current version of Umbraco.
* `umb-webhook-retrycount: {number of retries}`, where number of retries, is the current retry count for a given webhook request.
* `umb-webhook-event: {Umbraco.event}`, where event is the event that triggered the request, for example for Content published: `umb-webhook-event: Umbraco.ContentPublish`

## Configuring Webhooks

### Adding more events

To add more than the default events to Umbraco, you can leverage the provided `IUmbracoBuilder` and `IComposer` interfaces. Below is an example of how you can extend the list of available webhook events using a custom `WebhookComposer`:

```csharp
using Umbraco.Cms.Core.Composing;

public class CustomWebhookComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.WebhookEvents()
            .Clear()
            .AddCms(cmsBuilder =>
            {
                // Add your custom events here
                cmsBuilder
                    .AddDefault()
                    .AddContent()
                    .AddContentType()
                    .AddDataType()
                    .AddDictionary()
                    .AddDomain()
                    .AddFile()
                    .AddHealthCheck()
                    .AddLanguage()
                    .AddMedia()
                    .AddMember()
                    .AddPackage()
                    .AddPublicAccess()
                    .AddRelation()
                    .AddRelationType()
                    .AddUser();
            });
    }
}
```

This is a list of all the current events that are available through Umbraco. If you want them all enabled, you can use the following:

```csharp
builder.WebhookEvents().Clear().AddCms(false);
```

### Replace Webhook Events

Sometimes it is desirable to modify one of the standard Umbraco webhooks, for example, to change the Payload. This can be done by adding a custom implementation, as shown in the code example below:

```csharp
[WebhookEvent("Content Published", Constants.WebhookEvents.Types.Content)]
public class MyCustomContentPublishedWebhookEvent : WebhookEventContentBase<ContentPublishedNotification, IContent>
{
    private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
    private readonly IApiContentBuilder _apiContentBuilder;


    public MyCustomContentPublishedWebhookEvent(IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor<WebhookSettings> webhookSettings, IServerRoleAccessor serverRoleAccessor, IPublishedSnapshotAccessor publishedSnapshotAccessor, IApiContentBuilder apiContentBuilder) : base(webhookFiringService, webhookService, webhookSettings, serverRoleAccessor)
    {
        _publishedSnapshotAccessor = publishedSnapshotAccessor;
        _apiContentBuilder = apiContentBuilder;
    }

    public override string Alias => "Umbraco.ContentPublish";
    protected override IEnumerable<IContent> GetEntitiesFromNotification(ContentPublishedNotification notification) => notification.PublishedEntities;

    protected override object? ConvertEntityToRequestPayload(IContent entity)
    {
        if (_publishedSnapshotAccessor.TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) is false || publishedSnapshot!.Content is null)
        {
            return null;
        }

        IPublishedContent? publishedContent = publishedSnapshot.Content.GetById(entity.Key);

        return new
        {
            MyData = "Your data",
            PublishedContent = publishedContent is null ? null : _apiContentBuilder.Build(publishedContent)
        };
    }
}
```

Add the following line in a Composer to replace the standard Umbraco implementation with your custom implementation:

```csharp
public class MyComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.WebhookEvents().Replace<ContentPublishedWebhookEvent, MyCustomContentPublishedWebhookEvent>();
    }
}
```

### Webhook settings

Webhook settings can be configured in your `appsettings.*.json` and is in the `Umbraco::CMS` section, like so:

```json
  "Umbraco": {
    "CMS": {
      "Webhook": {
        "Enabled": true,
        "MaximumRetries": 5,
        "Period": "00:00:10",
        "EnableLoggingCleanup": true,
        "KeepLogsForDays": 30
      }
```

* **Enabled** - Whether or not webhooks are enabled.
* **MaximumRetries** - How many retries a given webhook request will do.
* **Period** - The period to wait between checks of any webhook requests needing to be fired.
* **EnableLoggingCleanup** - Whether of not to enable webhook log cleanup.
* **KeepLogsForDays** - How many days to keep webhook logs for.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.umbraco.com/umbraco-cms/13.latest/reference/webhooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
