> For the complete documentation index, see [llms.txt](https://docs.enate.net/enate-help/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.enate.net/enate-help/enate-apis-and-webhooks/webhooks/api-webhook-subscription.md).

# API Webhook Subscription

Webhook subscriptions are managed entirely through the API. There's no screen for them in Builder or Work Manager.

Two **GET** operations and three **POST** operations are available under Webhook Subscription. These are the APIs you use to create, view, amend and remove your Webhook subscriptions.

![](https://3859925423-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWYnDNwe3Cuo4zlGbs5%2F-MWnb30vDLQE7_ULyA2F%2F-MWnb6C1NkNl5Kwq6Mgs%2Fimage.png?alt=media\&token=78c0c101-2c53-4b24-98f0-abcedaea719a)

### Which API to Use

These operations live in the **Configuration API**, alongside the rest of Enate's configuration endpoints. The base address for your environment is the same one you use for the Configuration Swagger page:

```
https://yourplatform/configuration/WebHookSubscription/<operation>
```

See the APIs page for how to find your Swagger URL and how to authenticate with Application Credentials.

#### API versions

The Configuration API is versioned, and you choose a version with the `api-version` query string parameter:

```
https://yourplatform/configuration/WebHookSubscription/GetAllWebhookSubscriptions?api-version=4
```

Which versions are available depends on the feature wave your Enate environment is running:

| Version | `api-version` value                 | July 2026 Feature Wave                                                        | October 2026 Feature Wave                                                     |
| ------- | ----------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| 1       | `1`                                 | Available, superseded                                                         | Not available                                                                 |
| 2       | `2`                                 | Available, superseded                                                         | Available, superseded                                                         |
| 3       | `3`                                 | Current. This is the version you get if you don't supply `api-version` at all | Available, superseded                                                         |
| 4       | `4-preview` in July, `4` in October | Published as a preview version                                                | Current. This is the version you get if you don't supply `api-version` at all |

The five operations take the same requests and return the same responses in every version. The difference between versions is in how Enate reports a problem with a request, which is covered under Subscribing to an event on a closed work item, and under Rules Applied When You Subscribe. Send `api-version=4` to get the full explanation of what's wrong with a request.

{% hint style="info" %}
Note: the [legacy API](/enate-help/enate-apis-and-webhooks/apis/upgrading-api-versions/upgrading-from-the-2024.1-api-to-the-legacy-api.md) also exposes Webhook subscriptions, but only **SubscribeToWebhook** and **Unsubscribe**. The Get, Get all and Update operations aren't available there. Use the Configuration API if you need them. There's one other behavioural difference, covered under Subscribing to an event on a closed work item.
{% endhint %}

#### A note on JSON format

Responses use PascalCase field names, and requests are read whatever the case of their field names. Enumerations are sent and returned as **integer values, not names**. Send `"Webhook": 0`, not `"Webhook": "PacketCreated"`. The Configuration API rejects a request that supplies an enumeration as a string.

### GET Operations <a href="#get-all-webhook-subscriptions" id="get-all-webhook-subscriptions"></a>

* Get All Webhook Subscriptions - use this to list the Webhook subscriptions in your Enate environment.
* Get Webhook Subscription - use this to get the detail of one subscription.

#### Get All Webhook Subscriptions <a href="#get-all-webhook-subscriptions-2" id="get-all-webhook-subscriptions-2"></a>

Path: `/WebHookSubscription/GetAllWebhookSubscriptions`

* Type: GET
* Function: returns every Webhook subscription in your Enate environment, not just the ones your account created
* No parameters required
* Response code: 200

Each subscription in the list has these fields:

| Field                 | Type          | Required/Optional                             | Description                                                                                                                                                                       |
| --------------------- | ------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **GUID**              | String (GUID) | Always present                                | The identifier of the subscription. Use it for Get, Update and Unsubscribe.                                                                                                       |
| **Webhook**           | Integer       | Always present                                | The event subscribed to. 0 = PacketCreated, 1 = PacketUpdated, 2 = NewCommunication, 3 = BusinessObjectCreated, 4 = SpecificBusinessObjectUpdated, 5 = BusinessObjectTypeUpdated. |
| **FilterObjectGUID**  | String (GUID) | Null for type-scoped subscriptions            | The object the subscription is scoped to.                                                                                                                                         |
| **FilterObjectType**  | Integer       | Always present                                | The type of object being filtered by, from the EnateObjects enum.                                                                                                                 |
| **SubscriberURL**     | String        | Always present                                | The URL Enate posts messages to.                                                                                                                                                  |
| **Signature**         | String (GUID) | Always present                                | The value Enate sends in the `x-enate-signature` header for this subscription.                                                                                                    |
| **CustomHeader**      | String        | Empty when no custom header was supplied      | The custom HTTP header name.                                                                                                                                                      |
| **CustomHeaderValue** | String        | Null when no custom header value was supplied | The value sent in the custom header.                                                                                                                                              |

Expected response, a list of subscriptions in the following format:

```json
[
  {
    "GUID": "c14a9f02-6b53-4d88-b0e7-91f3a2c5d640",
    "Webhook": 0,
    "FilterObjectGUID": "3b5e7c9a-0d21-4e68-9f14-7c2a8b6d5e03",
    "FilterObjectType": 31,
    "SubscriberURL": "https://integrations.globex.example.com/enate/new-work-items",
    "Signature": "7e41b0c6-5a82-4f39-9d17-0b6c38e2a541",
    "CustomHeader": "Globex-source",
    "CustomHeaderValue": "enate-packet-created"
  },
  {
    "GUID": "9d2f61b8-3c47-4a05-8e93-25fb70c4a1de",
    "Webhook": 2,
    "FilterObjectGUID": "878409be-7886-eb11-b9ad-e86a64437383",
    "FilterObjectType": 81,
    "SubscriberURL": "https://integrations.globex.example.com/enate/communications",
    "Signature": "b6083d1f-47c2-4e5a-a930-1c8de4f60b27",
    "CustomHeader": "",
    "CustomHeaderValue": null
  }
]
```

#### Get Webhook Subscription <a href="#get-webhook-subscription" id="get-webhook-subscription"></a>

Path: `/WebHookSubscription/GetWebhookSubscription`

* Type: GET
* Function: returns the detail of a single Webhook subscription
* Parameter to set: `webhookSubscriptionGUID`, passed in the query string
* Parameter value: the GUID returned when the subscription was created

Example request:

```
GET https://yourplatform/configuration/WebHookSubscription/GetWebhookSubscription?webhookSubscriptionGUID=c14a9f02-6b53-4d88-b0e7-91f3a2c5d640&api-version=4
```

Response code 200, returning a single subscription with the fields listed above:

```json
{
  "GUID": "c14a9f02-6b53-4d88-b0e7-91f3a2c5d640",
  "Webhook": 0,
  "FilterObjectGUID": "3b5e7c9a-0d21-4e68-9f14-7c2a8b6d5e03",
  "FilterObjectType": 31,
  "SubscriberURL": "https://integrations.globex.example.com/enate/new-work-items",
  "Signature": "7e41b0c6-5a82-4f39-9d17-0b6c38e2a541",
  "CustomHeader": "Globex-source",
  "CustomHeaderValue": "enate-packet-created"
}
```

If no subscription exists with that GUID, the response code is 404.

### POST Operations

* Subscribe to Webhook - create a new subscription.
* Update Webhook Subscription - amend an existing subscription.
* Unsubscribe - permanently delete a subscription.

#### Subscribe to Webhook API <a href="#subscribe-to-webhook-api" id="subscribe-to-webhook-api"></a>

Path: `/WebHookSubscription/SubscribeToWebhook`

* Type: POST
* Function: creates a new subscription and returns the details of the subscription created

The request body takes these fields:

| Field                 | Type          | Required/Optional                                                                                                                                           | Description                                                                                                                                                                                    |
| --------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Webhook**           | Integer       | Required                                                                                                                                                    | The event to subscribe to, sent as its integer value.                                                                                                                                          |
| **FilterObjectType**  | Integer       | Required                                                                                                                                                    | The type of object being filtered by, from the EnateObjects enum.                                                                                                                              |
| **FilterObjectGUID**  | String (GUID) | Needed for PacketCreated, PacketUpdated, NewCommunication and SpecificBusinessObjectUpdated. Only PacketUpdated is refused without it. Not used by the rest | The object to scope the subscription to. PacketCreated, NewCommunication and SpecificBusinessObjectUpdated are saved without it, but then never send a message, so always supply it for those. |
| **SubscriberURL**     | String        | Required                                                                                                                                                    | An absolute `http` or `https` URL that can receive the Webhook message.                                                                                                                        |
| **CustomHeader**      | String        | Optional                                                                                                                                                    | A custom HTTP header name to add to every message. It can contain letters, digits and the characters ! # $ % & ' \* + - . ^ \_ \` \| \~, so it can't contain a space.                          |
| **CustomHeaderValue** | String        | Optional                                                                                                                                                    | The value to send in that custom header. It can only contain printable ASCII characters.                                                                                                       |

Request body:

```json
{
  "Webhook": 0,
  "FilterObjectGUID": "3b5e7c9a-0d21-4e68-9f14-7c2a8b6d5e03",
  "FilterObjectType": 31,
  "SubscriberURL": "https://integrations.globex.example.com/enate/new-work-items",
  "CustomHeader": "Globex-source",
  "CustomHeaderValue": "enate-packet-created"
}
```

Response code 200, with the new subscription under `Result`:

```json
{
  "Result": {
    "GUID": "c14a9f02-6b53-4d88-b0e7-91f3a2c5d640",
    "Webhook": 0,
    "FilterObjectGUID": "3b5e7c9a-0d21-4e68-9f14-7c2a8b6d5e03",
    "FilterObjectType": 31,
    "SubscriberURL": "https://integrations.globex.example.com/enate/new-work-items",
    "Signature": "7e41b0c6-5a82-4f39-9d17-0b6c38e2a541",
    "CustomHeader": "Globex-source",
    "CustomHeaderValue": "enate-packet-created"
  },
  "Messages": []
}
```

`Signature` is generated by Enate and is the value it will send in the `x-enate-signature` header of every message for this subscription, so store it.

If validation fails, the response code is 400, `Result` is null, and `Messages` holds the reasons. This is the response to a request whose `SubscriberURL` was `globex-integrations` rather than a full URL:

```json
{
  "Result": null,
  "Messages": [
    {
      "IsError": true,
      "MessageDescription": "The supplied subscription URL is not valid.",
      "Parameters": [],
      "RelatedObjectGUID": "0198f4c2-7a61-7d3e-9b05-6c41e8d23f7a",
      "RelatedObjectType": 990,
      "MessageID": 990296
    }
  ]
}
```

`RelatedObjectType` 990 is the Webhook Subscription object type, and `MessageID` identifies the specific rule that failed. `MessageDescription` is the readable form of the same thing, with any values substituted into it from `Parameters`. `RelatedObjectGUID` is the identifier Enate allocated to the subscription it was trying to create. Because the request failed, nothing was saved under it, so there's no point storing it.

See Rules Applied When You Subscribe for the full set of checks and the message each one produces.

{% hint style="info" %}
Note: the subscriber URL is the address of the system that will receive the Webhook messages. If you just want to see what a message looks like before you build anything, point a subscription at an endpoint you control in a non-production environment and log what arrives. Don't use a public request bin service: Webhook messages carry details of your work items, such as customer names and email addresses.
{% endhint %}

**Subscribing to an event on a closed work item**

You can't create a **PacketUpdated** subscription against a work item that is already Closed. The APIs handle the attempt differently:

| API                                | What happens                                                                                                                                                                                                                                             |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Configuration API, version 4       | Response code 400 with the standard envelope. `Result` is null and `Messages` holds `MessageID` 990815, "Cannot create a subscription for a closed packet."                                                                                              |
| Configuration API, versions 1 to 3 | Response code 400, with the plain text body `Cannot create subscription for a closed packet.`                                                                                                                                                            |
| Legacy API                         | From the July 2026 Feature Wave, response code 400. `Result` is null and `Messages` holds `MessageID` 990815, as in version 4. In the April 2026 Feature Wave and earlier, response code 200 with no validation messages, but no subscription is created |

If you're using the legacy API:

1. From the July 2026 Feature Wave, handle the 400 and look for `MessageID` 990815 in `Messages`. It means the work item is already Closed and no subscription was created.
2. On the April 2026 Feature Wave or earlier, don't rely on the 200. Check for the subscription afterwards with Get All Webhook Subscriptions in the Configuration API.
3. Treat a closed work item as final. Subscribing again won't succeed, so subscribe to work items before they close.

For example, a request for a **PacketUpdated** subscription on a Ticket that was closed yesterday:

```json
{
  "Webhook": 1,
  "FilterObjectGUID": "6f2a91c4-0b37-4d58-a9e2-34c7d1f08b65",
  "FilterObjectType": 81,
  "SubscriberURL": "https://integrations.globex.example.com/enate/ticket-updates"
}
```

is refused, by version 4 and by the legacy API from the July 2026 Feature Wave, with response code 400 and this body:

```json
{
  "Result": null,
  "Messages": [
    {
      "IsError": true,
      "MessageDescription": "Cannot create a subscription for a closed packet.",
      "Parameters": [],
      "RelatedObjectGUID": "0198f5a7-3c12-7b9e-8d40-91e6b2c7a3f5",
      "RelatedObjectType": 990,
      "MessageID": 990815
    }
  ]
}
```

#### Update Webhook Subcription <a href="#update-webhook-subcription" id="update-webhook-subcription"></a>

Path: `/WebHookSubscription/UpdateWebhookSubscription`

* Type: POST
* Function: amends an existing subscription

The request body is the same as SubscribeToWebhook plus the `GUID` of the subscription to update:

```json
{
  "GUID": "c14a9f02-6b53-4d88-b0e7-91f3a2c5d640",
  "Webhook": 0,
  "FilterObjectGUID": "3b5e7c9a-0d21-4e68-9f14-7c2a8b6d5e03",
  "FilterObjectType": 31,
  "SubscriberURL": "https://integrations.globex.example.com/enate/v2/new-work-items",
  "CustomHeader": "Globex-source",
  "CustomHeaderValue": "enate-packet-created"
}
```

The response has the same shape as SubscribeToWebhook.

{% hint style="warning" %}
**Updating a subscription does not change its signature.** The signature is generated once, when the subscription is created, and stays the same for the life of that subscription. If you need a new signature, unsubscribe and subscribe again.
{% endhint %}

This operation isn't available in the legacy API. To change a subscription there, unsubscribe and create a new one.

#### Unsubscribe (Delete Webhook Subscription) <a href="#delete-webhook-subscription" id="delete-webhook-subscription"></a>

Path: `/WebHookSubscription/Unsubscribe`

* Type: POST
* Takes a Webhook subscription GUID as the only parameter, passed in the query string
* Permanently deletes the subscription. There's no retire or deactivate option, and no reactivation. To start receiving the event again you create a new subscription, which gets a new GUID and a new signature

Example request:

```
POST https://yourplatform/configuration/WebHookSubscription/Unsubscribe?webHookSubscriptionGUID=c14a9f02-6b53-4d88-b0e7-91f3a2c5d640&api-version=4
```

Response code 200:

```json
{
  "Result": true,
  "Messages": []
}
```

If no subscription exists with that GUID, the response code is 404 with a plain text body, such as:

```
Web Hook Subscription with GUID 'c14a9f02-6b53-4d88-b0e7-91f3a2c5d640' not found.
```

### Rules Applied When You Subscribe

Enate checks a request to subscribe or to update a subscription against these rules. A request that breaks any of them is rejected with 400, nothing is saved, and every rule it broke is listed in `Messages`.

| MessageID | Rule                                                                                                                                                                                   | Message                                                                                                                                                          |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 990293    | `FilterObjectType` must be supplied.                                                                                                                                                   | Missing value, FilterObjectType is mandatory and must be supplied.                                                                                               |
| 990294    | The BusinessObjectCreated, BusinessObjectTypeUpdated and SpecificBusinessObjectUpdated events can only be used with a Company or a Schedule.                                           | Missing value, WebHook type is mandatory and must be supplied.                                                                                                   |
| 990295    | `SubscriberURL` must be supplied.                                                                                                                                                      | Missing value, Subscriber URL is mandatory and must be supplied.                                                                                                 |
| 990296    | `SubscriberURL` must be an absolute `http` or `https` URL.                                                                                                                             | The supplied subscription URL is not valid.                                                                                                                      |
| 990819    | A PacketUpdated subscription must have a `FilterObjectType` of Packet.                                                                                                                 | The filter object type supplied is not valid for the requested WebHook.                                                                                          |
| 990816    | A PacketUpdated subscription must have a `FilterObjectGUID`.                                                                                                                           | Missing value, a filter object must be supplied for this WebHook type.                                                                                           |
| 107       | The user making the request must have permission on the object named by `FilterObjectGUID`.                                                                                            | User with GUID '{0}' does not have the required permission to access the '{1}' with the GUID '{2}'.                                                              |
| 990817    | The object named by `FilterObjectGUID` must exist.                                                                                                                                     | The filter object supplied does not exist.                                                                                                                       |
| 990818    | The `FilterObjectType` must be one that Webhook subscriptions support.                                                                                                                 | The filter object type supplied is not supported for WebHook subscriptions.                                                                                      |
| 990372    | A subscription with the same settings can't already exist.                                                                                                                             | A WebHook subscription with the same settings already exists. Duplicate subscriptions are not permitted                                                          |
| 990813    | `CustomHeader` must only contain letters, digits and the characters ! # $ % & ' \* + - . ^ \_ \` \| \~.                                                                                | The custom header name contains characters that cannot be sent in an HTTP header. Use only letters, digits and the characters ! # $ % & ' \* + - . ^ \_ \` \| \~ |
| 990814    | `CustomHeaderValue` must only contain printable ASCII characters.                                                                                                                      | The custom header value contains characters that cannot be sent in an HTTP header. Only printable ASCII characters may be used.                                  |
| 990815    | You can't create a PacketUpdated subscription for a work item that's already Closed. Enate checks this only when you create a subscription, and only once the other rules have passed. | Cannot create a subscription for a closed packet.                                                                                                                |

`Webhook` itself isn't checked by these rules. A value that isn't one of the six events is rejected before they run, with a 400 problem response and no `Messages`. A request that leaves `Webhook` out isn't rejected: Enate reads it as 0, PacketCreated, so always send it, on Update as well as on Subscribe.

Messages 990813, 990814 and 990816 to 990819 are new in version 4. In versions 2 and 3, a request that breaks one of those rules is rejected with a 400 and a plain text message that tells you to use the latest version of the API, rather than the message above. Versions 2 and 3 answer a closed work item (990815) with the plain text message shown earlier. The API Enums page explains that response. Send the request with `api-version=4` to see which rule it broke.

### General API Validations <a href="#general-api-validations" id="general-api-validations"></a>

#### Authorization <a href="#authorization" id="authorization"></a>

Every one of these operations requires an authenticated account with a Builder role. A request with no bearer token, or with an expired one, is rejected with a 401. A request from an account that's authenticated but doesn't hold a Builder role is rejected with a 403.

![](https://3859925423-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWYnDNwe3Cuo4zlGbs5%2F-MWnb30vDLQE7_ULyA2F%2F-MWnc1MM21rFTndNjZ3c%2Fimage.png?alt=media\&token=0c85f281-0743-4b6e-ab0e-c4caf7e14a60)

Quick steps to check authorization behaviour:

1. Open the Swagger UI.
2. Don't log in to your test environment.
3. Send a request with all the valid details.
4. The API rejects the request as unauthorized.
5. Log in to your test environment.
6. Retry the same request.
7. The API returns a successful response, because the request is now authorized.

#### Invalid Requests <a href="#invalid-requests" id="invalid-requests"></a>

An invalid request returns a 400 Bad Request. There are two kinds:

* The request body couldn't be read at all, for example malformed JSON, an enumeration supplied as a string, or a field the API doesn't recognise. You get a 400 with no `Messages` array.
* The request was read but failed Enate's validation rules. You get a 400 with the reasons in the `Messages` array, as shown under Subscribe to Webhook API.

![](https://3859925423-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWYnDNwe3Cuo4zlGbs5%2F-MWnb30vDLQE7_ULyA2F%2F-MWnc8YyoAVD60fvx_8F%2Fimage.png?alt=media\&token=8dedc586-05c9-4710-8d86-519259e2dd0e)

Common causes of a bad request:

* An incorrect GUID value
* Syntax errors in the request JSON
* An enumeration value Enate doesn't recognise

The API Errors and Status Codes page lists every response Enate's APIs can return, and what to do about each:

{% content-ref url="/pages/JlIMonf1Oe8RGGRS5erd" %}
[API Errors and Status Codes](/enate-help/enate-apis-and-webhooks/apis/api-errors-and-status-codes.md)
{% endcontent-ref %}


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.enate.net/enate-help/enate-apis-and-webhooks/webhooks/api-webhook-subscription.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
