> For the complete documentation index, see [llms.txt](https://developer.emporix.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.emporix.io/ce/management-dashboard/administration/webhooks.md).

# Webhooks

The **Webhooks** section allows you to manage available webhooks that you can connect to other systems you use in your company.

<figure><img src="/files/sOqygNHVWwfhGsa0eDBy" alt=""><figcaption></figcaption></figure>

Webhooks is a convenient tool that allows you to subscribe to certain events that are happening in the Emporix Commerce Engine to get instant information about them. For example, you might want to subscribe to all instances when an order is created in the system and send a message about it to your external order management application for further processing.

## Configuring webhook service

To receive notifications about events happening in the system, firstly configure the webhook service according to your needs. To choose the relevant strategy, follow these steps:

{% stepper %}
{% step %}
Go to **Administration** -> **Webhooks**.
{% endstep %}

{% step %}
Select one of the available [strategies](#webhook-strategies).
{% endstep %}

{% step %}
Depending on the selected option, you might be asked to provide more details to enable the notifications. Confirm with **Active**.
{% endstep %}
{% endstepper %}

## Webhook strategies

Emporix offers the following strategies you can choose for the webhook event gateway:

* [Shared account - Svix](#shared-account-svix-strategy)
* [Licensed account - Svix](#licensed-account-svix-strategy)
* [Other - HTTP](#other-http-strategy)

You can have only one strategy active at a time.

### Shared account - SVIX strategy

The default solution to handle webhook events that comes with Commerce Engine is Svix-shared strategy. You can use this strategy out-of-the-box up to the set monthly limit.

<figure><img src="/files/dH1CokfZbpn8x0OmvIRy" alt="" width="450"><figcaption></figcaption></figure>

**Svix Dashboard**

With Svix-shared webhook strategy, you get access to Svix dashboard. This is the place to connect the webhooks to specific endpoints.

{% stepper %}
{% step %}
In **Administration** -> **Webhooks**, choose **Open Svix Dashboard**. You're redirected to Svix.
{% endstep %}

{% step %}
Go to **Endpoints** and choose **Add endpoint**.

* In **Endpoint URL**, provide a URL of the system you want to connect the webhooks to.
* Choose the event types of your interest and choose **Create** to start receiving notifications.
  {% endstep %}
  {% endstepper %}

Now, in Svix Dashboard, you can see all the events of the types that you have subscribed to. You are able to check the payload details of each particular event message sent to the external system. You can also check the schema of a particular event type under the **Event catalog**.

**Viewing your webhook usage**

{% hint style="danger" %}
With the Svix-shared strategy, the maximum number of events per tenant is limited to 5000/month. The limit resets on the first day of each month. After you exceed the set limit, the requests do not get sent. For further information about the limits, please contact the Sales department at <sales@emporix.com>.
{% endhint %}

You can keep the webhooks usage under control by checking the usage statistics.

In **Administration** -> **Webhooks**, you can see your current monthly usage. By choosing the **Webhook usage**, you get a detailed overview of the webhooks usage in a particular period.

### Licensed account - SVIX strategy

Choose the Svix strategy if you need more flexibility and want to connect your independent Svix subscription to Commerce Engine system. To activate this strategy, provide an API key that you get directly from Svix. With the Svix strategy, the monthly webhook traffic limit depends on your own Svix plan.

<figure><img src="/files/QECaKIp1EoABbVVpa7Us" alt="" width="450"><figcaption></figcaption></figure>

### Other - HTTP strategy

This strategy allows you to receive webhook event notifications as HTTP `POST` requests. When you activate the HTTP strategy, provide a global **destination URL** that is used when an event type has no custom endpoints configured.

<figure><img src="/files/IuM3MWruJmbd66Aw5qhd" alt="HTTP webhook strategy configuration" width="450"><figcaption><p>HTTP strategy settings in Management Dashboard</p></figcaption></figure>

Optionally, you can secure HTTP communication with an **HMAC** secret. The HMAC (keyed-Hash Message Authentication Code) security layer verifies if the checksum of data that came to the destination point is correct. HMAC is a type of authentication technique that uses a hash function and a secret key. You can use it to sign a request with a shared secret.

{% hint style="info" %}
For more information on how to secure the requests with HMAC encryption, see [HTTP Webhook Strategy - HMAC Configuration](/ce/system-management/webhooks-user-guide/hmac-configuration.md).
{% endhint %}

With **Custom Headers**, you can define a list of headers which are attached to the API request sent through the webhooks. For example, use custom headers to provide the following:

* authentication and authorization measures: API keys, bearer tokens, or other security tokens
* context information: some additional information about the context of a request, for example the request origin, the response preferred language, or user-defined preferences

Moreover, each HTTP request has `emporix-event-publish-time` header attached which contains timestamp in RFC3339 UTC "Zulu" format and provides information about the time at which the message was published.

#### Multiple webhook targets

With the HTTP strategy, you can register several HTTP targets for the same event type. Each target can have its own destination URL, HMAC secret, custom headers, optional JsonPath filter, and payload field selection.

To configure endpoints for a subscribed event, select the event from the list and choose the **Edit** icon. The event dialog has two tabs:

* **Event defaults** – default payload fields inherited by endpoints that do not define a custom field selection
* **Endpoints** – list of HTTP targets for this event type

<figure><img src="/files/ZBBR2mSP3wNruHxzBhIt" alt="Event defaults tab with payload field toggles"><figcaption><p>Event defaults — default payload fields for the event type</p></figcaption></figure>

When at least one custom endpoint is configured, an info banner indicates that the global destination URL is not used for that event type.

**Adding and editing endpoints**

On the **Endpoints** tab, choose **+ Add** to register another target for the same event. For each endpoint you can configure:

* **Name** – descriptive label for the integration
* **Destination URL** – required HTTP endpoint that receives the event
* **HMAC secret** – optional per-endpoint signing secret; when set, it overrides the global HTTP secret for this target
* **Custom headers** – optional key/value headers for this target
* **Filter (JsonPath)** – optional Jayway JsonPath predicate evaluated against the event payload
* **Payload fields** – **Inherit event defaults** or **Customize for this endpoint**
* **Active** – delivery toggle; when off, this endpoint does not receive events

<figure><img src="/files/9x5ALoan3R9ZAEadaMSL" alt="Endpoints tab with endpoint editor and JsonPath filter"><figcaption><p>Endpoints — multiple HTTP targets for a single event type</p></figcaption></figure>

{% hint style="success" %}
**Example use cases**

* Send declined quotes to a CRM endpoint while routing other quote updates elsewhere: `$[?(@.status.value == 'DECLINED')]`.
* Deliver custom entity updates only for a specific entity type: `$[?(@.type == 'contract')]` on `schema.custom-instance-updated`.
* Sync full customer payloads to a CRM and a reduced field set to an analytics tool by customizing payload fields per endpoint.
  {% endhint %}

**JsonPath filters**

The **Filter (JsonPath)** field accepts an optional Jayway JsonPath predicate. Filters are evaluated against the sanitized event payload.

* If the filter is empty or omitted, all events of the subscribed event type match the endpoint.
* If the filter is set, the endpoint receives the event only when the predicate evaluates to true.
* Invalid or malformed JsonPath expressions are rejected with a validation error and are not saved.

Use the predicate form `$[?(@.<path> <operator> <value>)]`. Match the path to the field shape in the event payload:

* Use a top-level field when the value is a string – for example `@.status` on order events (`"status": "DECLINED"`).
* Use a nested path when the value sits on an object – for example `@.status.value` on quote events, where `status` is `{ "value": "DECLINED", ... }`.

The JsonPath help overlay inserts the string-field examples. Adjust the path when you filter a nested object.

| Example                                         | Expression                                                                          |
| ----------------------------------------------- | ----------------------------------------------------------------------------------- |
| Match by status (string field)                  | `$[?(@.status == 'DECLINED')]`                                                      |
| Match nested status (quotes)                    | `$[?(@.status.value == 'DECLINED')]`                                                |
| Custom entity type (`schema.custom-instance-*`) | `$[?(@.type == 'contract')]`                                                        |
| Match by code                                   | `$[?(@.code == 'abc')]`                                                             |
| AND (all conditions)                            | `$[?(@.status == 'DECLINED' && @.channel == 'web')]`                                |
| OR (any condition)                              | `$[?(@.status == 'DECLINED' \|\| @.status == 'CANCELLED')]`                         |
| AND + OR with grouping                          | `$[?(@.channel == 'web' && (@.status == 'DECLINED' \|\| @.status == 'CANCELLED'))]` |

<figure><img src="/files/IpB18dIUxjy9Ktcf3EMS" alt="JsonPath filter help overlay with examples"><figcaption><p>JsonPath filter help with clickable examples</p></figcaption></figure>

{% hint style="info" %}
For API request and response examples, including invalid filter validation (`400`) and multi-entry configuration, see the [Webhook Service Tutorials](/api-references/api-guides/webhooks/webhook-service/webhooks-tutorial.md).
{% endhint %}

## Subscribing to webhook events

Apart from choosing the webhook strategy that is right for you, decide which specific events you'd like to listen to. You can subscribe to Commerce Engine events across services, including Schema custom entity events such as `schema.custom-instance-created`, `schema.custom-instance-updated`, and `schema.custom-instance-deleted`.

{% stepper %}
{% step %}
In **Administration** -> **Webhooks**, expand the service of your interest to see the list of available events. Turn on the slide under **Status** column to switch the webhook on.
{% endstep %}

{% step %}
Go to edit mode by choosing the **Edit** icon.

<figure><img src="/files/s6fFbmQSkY330FiQ5cnn" alt="Webhook event subscription editor" width="600"><figcaption><p>Edit a webhook event subscription</p></figcaption></figure>
{% endstep %}

{% step %}
Select the attributes you'd like to see in the webhook payload message. Confirm with **Update subscription**.

<figure><img src="/files/oYD9IbMYK454sk7lIJsT" alt="Payload attribute selection for a webhook subscription"><figcaption><p>Select payload attributes for the subscription</p></figcaption></figure>
{% endstep %}
{% endstepper %}

{% hint style="info" %}
For the HTTP strategy, after you subscribe to an event, you can open the same event dialog to manage **Event defaults** and **Endpoints**. Pair a Schema custom-instance subscription with an optional JsonPath filter on `type` when you only want specific custom entity types delivered to a target.
{% endhint %}

{% hint style="success" %}
**Learn about the `index.item-updated` event's specific behavior**

The `index.item-updated` webhook event is emitted whenever there is a change on an item in the system - the index is updated with the new information.\
For the event to be triggered, a product must have at least one defined **price**, as it is the price that determines products indexing on a specific site.\
Bear in mind all the events are site-specific, which means that they are linked to activities happening on particular sites.\
The prices are also site-specific, and a single price can be associated with multiple sites.\
The number of events triggered in the system depends on **the number of sites** assigned to a specific product’s prices, with one event emitted per each site.

Example:
{% endhint %}

| productid | price with associated sites                | number of emitted events | sites the event was emitted to |
| --------- | ------------------------------------------ | ------------------------ | ------------------------------ |
| `123`     | `$10` - site `A`, `B`                      | 2                        | `A`, `B`                       |
| `234`     | `$10` - site `A`, `$15`- site`A`, `B`, `C` | 3                        | `A`, `B`, `C`                  |
| `345`     | no price                                   | 0                        | none                           |

{% hint style="success" %}
A product `123` has one assigned price `$10`, associated with two sites `A` and `B`. When you update the product `123`, the number of emitted `index.item-updated` events is **2** as there are two sites associated with the product price. A product `234` has two assigned prices: `$10` associated with site `A` and `$15` associated with site `A`, `B`, and `C`. So when you update the product `234`, the `index.item-updated` event runs **3** times, as there are three sites affected.

* A product *123* has one assigned price of *$10*, associated with two sites *A* and *B*. When you update the product *123*, the number of emitted `index.item-updated` events is **2** as there are two sites associated with the product price.
* A product *234* has two assigned prices: *$10* associated with site *A* and *$15* associated with site *A*, *B*, and *C*. So when you update the product *234*, the `index.item-updated` event runs **3** times, as there are three sites affected.
* A product *345* has no defined price. So when you update the *345* product, the `index.item-updated` is not emitted as no site is associated with the product.
  {% endhint %}

{% hint style="info" %}
For more information on Webhooks, see the following documentation:

* System Management guide - [Webhook Event Publishing](/ce/system-management/webhooks-user-guide.md) and [HTTP Webhook Strategy - HMAC Configuration](/ce/system-management/webhooks-user-guide/hmac-configuration.md)
* API Tutorial - [Webhook Service Tutorials](/api-references/api-guides/webhooks/webhook-service/webhooks-tutorial.md)
* Example integration:
  * [HTTP Webhook Strategy - Integration with Azure Service Bus](/ce/system-management/webhooks-user-guide/azure-service-bus-integration.md)
  * [HTTP Webhook Strategy - Integration with Amazon Simple Queue Service (SQS)](/ce/system-management/webhooks-user-guide/amazon-sqs-integration.md)
    {% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://developer.emporix.io/ce/management-dashboard/administration/webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
