Repository: nautobot/nautobot
Pull request #7030: Improved Nautobot Webhooks Documentation with Additional Context and Examples
Author: login: ssganesh035
Created: 2025-03-15T17:03:11Z | Merged: 2025-03-21T15:59:57Z

1. Added structured tables for better readability.
2. Expanded explanations for configuration options.
3. Provided a detailed Jinja2 templating guide with a Slack integration example.
4. Clarified webhook processing using Redis and Celery.
5. Improved troubleshooting steps, including the built-in webhook receiver.


Diff:
diff --git a/changes/7030.documentation b/changes/7030.documentation
new file mode 100644
index 00000000000..1d1cae41c82
--- /dev/null
+++ b/changes/7030.documentation
@@ -0,0 +1 @@
+Improved Nautobot Webhooks documentation with additional context and examples.
diff --git a/nautobot/docs/user-guide/administration/tools/nautobot-server.md b/nautobot/docs/user-guide/administration/tools/nautobot-server.md
index c300ef961bf..8a4c393f06f 100644
--- a/nautobot/docs/user-guide/administration/tools/nautobot-server.md
+++ b/nautobot/docs/user-guide/administration/tools/nautobot-server.md
@@ -842,4 +842,4 @@ Example output:
 Listening on port http://localhost:9000. Stop with CONTROL-C.
 ```
 
-Please see the guide on [Troubleshooting Webhooks](../../platform-functionality/webhook.md#troubleshooting) for more information.
+Please see the guide on [Troubleshooting Webhooks](../../platform-functionality/webhook.md#troubleshooting-webhooks) for more information.
diff --git a/nautobot/docs/user-guide/platform-functionality/webhook.md b/nautobot/docs/user-guide/platform-functionality/webhook.md
index e1da0c59222..6dfeafc831b 100644
--- a/nautobot/docs/user-guide/platform-functionality/webhook.md
+++ b/nautobot/docs/user-guide/platform-functionality/webhook.md
@@ -1,54 +1,66 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Indicates whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. It allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation of multiple changes associated with a single request. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
@@ -92,44 +104,45 @@ If no body template is specified, the request body will be populated with a JSON
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
 
-## Troubleshooting
+## Troubleshooting Webhooks
 
-To assist with verifying that the content of outgoing webhooks is rendered correctly, Nautobot provides a simple HTTP listener that can be run locally to receive and display webhook requests. First, modify the target URL of the desired webhook to `http://localhost:9000/`. This will instruct Nautobot to send the request to the local server on TCP port 9000. Then, start the webhook receiver service from the Nautobot root directory:
+To inspect outgoing webhooks, you can use a local HTTP listener. Nautobot provides a built-in webhook receiver that logs incoming requests:
 
-```no-highlight
-nautobot-server webhook_receiver
-```
+1. Set the webhook URL to `http://localhost:9000/`.
+2. Start the webhook receiver:
 
-Example output:
+    ```sh
+    nautobot-server webhook_receiver
+    ```
 
-```no-highlight
-Listening on port http://localhost:9000. Stop with CONTROL-C.
-```
+    Example output:
 
-You can test the receiver itself by sending any HTTP request to it. For example:
+    ```sh
+    Listening on port http://localhost:9000. Stop with CONTROL-C.
+    ```
 
-```no-highlight
-curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
-```
+3. Send a test request:
 
-The server will print output similar to the following:
+    ```sh
+    curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
+    ```
 
-```no-highlight
-[1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
-Host: localhost:9000
-User-Agent: curl/7.58.0
-Accept: */*
-Content-Length: 14
-Content-Type: application/x-www-form-urlencoded
+    The listener will output:
 
-{"foo": "bar"}
-------------
-```
+    ```sh
+    [1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
+    Host: localhost:9000
+    Content-Type: application/json
+    Content-Length: 14
+
+    {"foo": "bar"}
+    ```
 
-Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
+> **Alternative Testing Tools:**
+> Instead of using the built-in webhook receiver, you can test webhooks with external services like [Beeceptor](https://beeceptor.com/) or [Pipedream RequestBin](https://pipedream.com/requestbin). These tools let you inspect webhook payloads and troubleshoot integration issues.
 
-Now, when the Nautobot webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `celery worker` process is running.
+If a webhook does not trigger as expected, ensure that the **Celery worker** process is running and check the Nautobot logs for errors.


Reviews:
user: login: HanlinMiao
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T16:32:40Z
user: login: HanlinMiao
body: Thanks for the PR, we also need a changelog fragment `7030.documentation` in the `/changes` directory
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T16:38:13Z
user: login: glennmatthews
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T13:12:22Z
user: login: glennmatthews
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T14:58:27Z
user: login: glennmatthews
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:42:16Z
user: login: glennmatthews
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:48:31Z
user: login: glennmatthews
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T19:45:49Z

Review comments:
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: HanlinMiao
body: ```suggestion
| **Enabled** | Indicates whether the webhook is active. |
```
created_at: 2025-03-17T16:23:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: HanlinMiao
body: We should still keep mentioning the fields `additional_headers` and `body_template` that support Jinja2 templating.
created_at: 2025-03-17T16:28:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation. |
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: HanlinMiao
body: ```suggestion
| `request_id` | A unique request ID for correlation of multiple changes associated with a single request. |
```
created_at: 2025-03-17T16:29:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
-    "data": {
-        "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-        "display": "Campus A",
-        "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-        "name": "Campus A",
-        "status": {
-            "display": "Active",
-            "id": "363a431c-c784-40b5-8513-758cafd174ad",
-            "url": "/api/extras/statuses/363a431c-c784-40b5-8513-758cafd174ad/",
-            "name": "Active",
-            "created": "2023-02-14T00:00:00Z",
-            "last_updated": "2023-02-14T19:40:13.216150Z"
-        },
-        ...
-    },
+    "data": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
     "snapshots": {
         "prechange": null,
-        "postchange": {
-            "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-            "asn": null,
-            "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-            "name": "Campus A",
-            ...
-        },
-        "differences": {
-            "removed": null,
-            "added": {
-                "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-                "asn": null,
-                "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-                "name": "Campus A",
-                ...
-            }
-        }
+        "postchange": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
+        "differences": { "added": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" } }
     }
 }
 ```
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
 
-## Troubleshooting
+## Troubleshooting Webhooks
 
-To assist with verifying that the content of outgoing webhooks is rendered correctly, Nautobot provides a simple HTTP listener that can be run locally to receive and display webhook requests. First, modify the target URL of the desired webhook to `http://localhost:9000/`. This will instruct Nautobot to send the request to the local server on TCP port 9000. Then, start the webhook receiver service from the Nautobot root directory:
+To inspect outgoing webhooks, you can use a local HTTP listener. Nautobot provides a built-in webhook receiver that logs incoming requests:
 
-```no-highlight
-nautobot-server webhook_receiver
-```
+1. Set the webhook URL to `http://localhost:9000/`.
+2. Start the webhook receiver:
 
-Example output:
+    ```sh
+    nautobot-server webhook_receiver
+    ```
 
-```no-highlight
-Listening on port http://localhost:9000. Stop with CONTROL-C.
-```
+    Example output:
 
-You can test the receiver itself by sending any HTTP request to it. For example:
+    ```sh
+    Listening on port http://localhost:9000. Stop with CONTROL-C.
+    ```
 
-```no-highlight
-curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
-```
+3. Send a test request:
 
-The server will print output similar to the following:
+    ```sh
+    curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
+    ```
 
-```no-highlight
-[1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
-Host: localhost:9000
-User-Agent: curl/7.58.0
-Accept: */*
-Content-Length: 14
-Content-Type: application/x-www-form-urlencoded
+    The listener will output:
 
-{"foo": "bar"}
-------------
-```
+    ```sh
+    [1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
+    Host: localhost:9000
+    Content-Type: application/json
+    Content-Length: 14
+
+    {"foo": "bar"}
+    ```
 
-Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
+> **Alternative Testing Tools:**
+> Instead of using the built-in webhook receiver, you can test webhooks with external services like [Beeceptor](https://beeceptor.com/) or [Pipedream RequestBin](https://pipedream.com/requestbin). These tools let you inspect webhook payloads and troubleshoot integration issues.
 
-Now, when the Nautobot webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `celery worker` process is running.
+If a webhook does not trigger as expected, ensure that the **Celery worker** process is running and check the Nautobot logs for errors.
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: HanlinMiao
body: ```suggestion
If a webhook does not trigger as expected, ensure that the **celery worker** process is running and check the Nautobot logs for errors.
```
created_at: 2025-03-17T16:32:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
-    "data": {
-        "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-        "display": "Campus A",
-        "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-        "name": "Campus A",
-        "status": {
-            "display": "Active",
-            "id": "363a431c-c784-40b5-8513-758cafd174ad",
-            "url": "/api/extras/statuses/363a431c-c784-40b5-8513-758cafd174ad/",
-            "name": "Active",
-            "created": "2023-02-14T00:00:00Z",
-            "last_updated": "2023-02-14T19:40:13.216150Z"
-        },
-        ...
-    },
+    "data": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
     "snapshots": {
         "prechange": null,
-        "postchange": {
-            "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-            "asn": null,
-            "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-            "name": "Campus A",
-            ...
-        },
-        "differences": {
-            "removed": null,
-            "added": {
-                "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-                "asn": null,
-                "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-                "name": "Campus A",
-                ...
-            }
-        }
+        "postchange": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
+        "differences": { "added": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" } }
     }
 }
 ```
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
 
-## Troubleshooting
+## Troubleshooting Webhooks
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: HanlinMiao
body: We need to change the link on line 845 in `nautobot-server.md` to match this header.
created_at: 2025-03-17T16:35:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Indicates whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. It allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation of multiple changes associated with a single request. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
-    "data": {
-        "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-        "display": "Campus A",
-        "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-        "name": "Campus A",
-        "status": {
-            "display": "Active",
-            "id": "363a431c-c784-40b5-8513-758cafd174ad",
-            "url": "/api/extras/statuses/363a431c-c784-40b5-8513-758cafd174ad/",
-            "name": "Active",
-            "created": "2023-02-14T00:00:00Z",
-            "last_updated": "2023-02-14T19:40:13.216150Z"
-        },
-        ...
-    },
+    "data": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: glennmatthews
body: Is this change accurate? I would expect a `created` snapshot to include the full data (as in the `before` diffs), not just the `id` and the `name`.
created_at: 2025-03-18T13:10:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Indicates whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. It allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation of multiple changes associated with a single request. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
-    "data": {
-        "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-        "display": "Campus A",
-        "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-        "name": "Campus A",
-        "status": {
-            "display": "Active",
-            "id": "363a431c-c784-40b5-8513-758cafd174ad",
-            "url": "/api/extras/statuses/363a431c-c784-40b5-8513-758cafd174ad/",
-            "name": "Active",
-            "created": "2023-02-14T00:00:00Z",
-            "last_updated": "2023-02-14T19:40:13.216150Z"
-        },
-        ...
-    },
+    "data": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
     "snapshots": {
         "prechange": null,
-        "postchange": {
-            "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-            "asn": null,
-            "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-            "name": "Campus A",
-            ...
-        },
-        "differences": {
-            "removed": null,
-            "added": {
-                "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-                "asn": null,
-                "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-                "name": "Campus A",
-                ...
-            }
-        }
+        "postchange": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
+        "differences": { "added": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" } }
     }
 }
 ```
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: glennmatthews
body: I'm actually not sure that (after the move from RQ to Celery) we actually still have the ability to retry webhooks via the admin UI. Would be good to test and verify.
created_at: 2025-03-18T13:11:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1 @@
+Improved Nautobot Webhooks Documentation with Additional Context and Examples
path: changes/7030.documentation
user: login: glennmatthews
body: ```suggestion
Improved Nautobot Webhooks documentation with additional context and examples.
```
created_at: 2025-03-18T13:12:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,67 +81,53 @@ If no body template is specified, the request body will be populated with a JSON
     },
     "snapshots": {
         "prechange": null,
-        "postchange": {
-            "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-            "asn": null,
-            "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-            "name": "Campus A",
-            ...
-        },
-        "differences": {
-            "removed": null,
-            "added": {
-                "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-                "asn": null,
-                "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-                "name": "Campus A",
-                ...
-            }
-        }
+        "postchange": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
+        "differences": { "added": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" } }
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: glennmatthews
body: Same comment on these changes, seems wrong to me?
created_at: 2025-03-18T14:58:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -92,44 +104,45 @@ If no body template is specified, the request body will be populated with a JSON
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
 
-## Troubleshooting
+## Troubleshooting Webhooks
 
-To assist with verifying that the content of outgoing webhooks is rendered correctly, Nautobot provides a simple HTTP listener that can be run locally to receive and display webhook requests. First, modify the target URL of the desired webhook to `http://localhost:9000/`. This will instruct Nautobot to send the request to the local server on TCP port 9000. Then, start the webhook receiver service from the Nautobot root directory:
+To inspect outgoing webhooks, you can use a local HTTP listener. Nautobot provides a built-in webhook receiver that logs incoming requests:
 
-```no-highlight
-nautobot-server webhook_receiver
-```
+1. Set the webhook URL to `http://localhost:9000/`.
+2. Start the webhook receiver:
 
-Example output:
+    ```sh
+    nautobot-server webhook_receiver
+    ```
 
-```no-highlight
-Listening on port http://localhost:9000. Stop with CONTROL-C.
-```
+    Example output:
 
-You can test the receiver itself by sending any HTTP request to it. For example:
+    ```sh
+    Listening on port http://localhost:9000. Stop with CONTROL-C.
+    ```
 
-```no-highlight
-curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
-```
+3. Send a test request:
 
-The server will print output similar to the following:
+    ```sh
+    curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
+    ```
 
-```no-highlight
-[1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
-Host: localhost:9000
-User-Agent: curl/7.58.0
-Accept: */*
-Content-Length: 14
-Content-Type: application/x-www-form-urlencoded
+    The listener will output:
 
-{"foo": "bar"}
-------------
-```
+    ```sh
+    [1] Tue, 07 Apr 2020 17:44:02 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
+    Host: localhost:9000
+    Content-Type: application/json
+    Content-Length: 14
+
+    {"foo": "bar"}
+    ```
 
-Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
+> **Alternative Testing Tools:**
+> Instead of using the built-in webhook receiver, you can test webhooks with external services like [Beeceptor](https://beeceptor.com/) or [Pipedream RequestBin](https://pipedream.com/requestbin). These tools let you inspect webhook payloads and troubleshoot integration issues.
 
-Now, when the Nautobot webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `celery worker` process is running.
+If a webhook does not trigger as expected, ensure that the **celery worker** process is running and check the Nautobot logs for errors.
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: glennmatthews
body: ```suggestion
If a webhook does not trigger as expected, ensure that the **Celery worker** process is running and check the Nautobot logs for errors.
```
created_at: 2025-03-20T14:48:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,135 +1,119 @@
 # Webhooks
 
-A webhook is a mechanism for conveying to some external system a change that took place in Nautobot. For example, you may want to notify a monitoring system whenever the status of a device is updated in Nautobot. This can be done by creating a webhook for the device model in Nautobot and identifying the webhook receiver. When Nautobot detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the web UI under Extensibility > Webhooks.
-
-## Configuration
-
-* **Name** - A unique name for the webhook. The name is not included with outbound messages.
-* **Object type(s)** - The type or types of Nautobot object that will trigger the webhook.
-* **Enabled** - If unchecked, the webhook will be inactive.
-* **Events** - A webhook may trigger on any combination of create, update, and delete events. At least one event type must be selected.
-* **HTTP method** - The type of HTTP request to send. Options include `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
-* **URL** - The fuly-qualified URL of the request to be sent. This may specify a destination port number if needed.
-* **HTTP content type** - The value of the request's `Content-Type` header. (Defaults to `application/json`)
-* **Additional headers** - Any additional headers to include with the request (optional). Add one header per line in the format `Name: Value`. Jinja2 templating is supported for this field (see below).
-* **Body template** - The content of the request being sent (optional). Jinja2 templating is supported for this field (see below). If blank, Nautobot will populate the request body with a raw dump of the webhook context. (If the HTTP content-type is set to `application/json`, this will be formatted as a JSON object.)
-* **Secret** - A secret string used to prove authenticity of the request (optional). This will append a `X-Hook-Signature` header to the request, consisting of a HMAC (SHA-512) hex digest of the request body using the secret as the key.
-* **SSL verification** - Uncheck this option to disable validation of the receiver's SSL certificate. (Disable with caution!)
-* **CA file path** - The file path to a particular certificate authority (CA) file to use when validating the receiver's SSL certificate (optional).
+A webhook is a mechanism for notifying an external system when a change occurs in Nautobot. For example, you might want to alert a monitoring tool whenever a device's status is updated. This can be achieved by creating a webhook for the device model and specifying a receiver URL. When Nautobot detects a change, it sends an HTTP request with details about the event and the user who triggered it.
+
+Webhooks are managed via the web UI under **Extensibility > Webhooks**.
+
+## Configuring a Webhook
+
+When setting up a webhook, you need to define the following parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Name** | A unique name for the webhook (not included in outgoing messages). |
+| **Object type(s)** | The type(s) of Nautobot objects that trigger the webhook. |
+| **Enabled** | Determines whether the webhook is active. |
+| **Events** | Select one or more events: `create`, `update`, or `delete`. |
+| **HTTP method** | The type of HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). |
+| **URL** | The fully qualified URL of the receiver. You can specify a port if needed. |
+| **HTTP content type** | Sets the `Content-Type` header (default: `application/json`). |
+| **Additional headers** | Custom headers, one per line (`Name: Value`). Supports Jinja2 templating. |
+| **Body template** | Custom request body. Supports Jinja2 templating. If empty, Nautobot sends the default payload. |
+| **Secret** | A secret string used for HMAC (SHA-512) authentication. The webhook request includes an `X-Hook-Signature` header. |
+| **SSL verification** | If unchecked, Nautobot skips SSL certificate validation (use with caution). |
+| **CA file path** | Specifies a custom CA file for SSL validation. |
 
 ## Jinja2 Template Support
 
-[Jinja2 templating](https://jinja.palletsprojects.com/) is supported for the `additional_headers` and `body_template` fields. This enables the user to convey object data in the request headers as well as to craft a customized request body. Request content can be crafted to enable the direct interaction with external systems by ensuring the outgoing message is in a format the receiver expects and understands.
+[Jinja2 templating](https://jinja.palletsprojects.com/) allows you to customize headers and request bodies dynamically. This is useful for formatting webhook payloads to match external system expectations.
 
-For example, you might create a Nautobot webhook to [trigger a Slack message](https://api.slack.com/messaging/webhooks) any time an IP address is created. You can accomplish this using the following configuration:
+Example: Trigger a Slack message when a new IP address is created.
 
-* Object type: IPAM > IP address
-* HTTP method: `POST`
-* URL: Slack incoming webhook URL
-* HTTP content type: `application/json`
-* Body template: `{"text": "IP address {{ data['address'] }} was created by {{ username }}!"}`
+**Webhook Configuration:**
 
-### Available Context
+- **Object type**: IPAM > IP address
+- **HTTP method**: `POST`
+- **URL**: Slack incoming webhook URL
+- **HTTP content type**: `application/json`
+- **Body template**:
+  
+  ```json
+  {"text": "IP address {{ data['address'] }} was created by {{ username }}!"}
+  ```
 
-The following data is available as context for Jinja2 templates:
+### Available Context Variables
 
-* `event` - The type of event which triggered the webhook: created, updated, or deleted.
-* `model` - The Nautobot model which triggered the change.
-* `timestamp` - The time at which the event occurred (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format).
-* `username` - The name of the user account associated with the change.
-* `request_id` - The unique request ID. This may be used to correlate multiple changes associated with a single request.
-* `data` - A serialized representation of the object _after_ the change was made. This is typically equivalent to the model's representation in Nautobot's REST API.
-* `snapshots` - snapshots of the serialized object state both before and after the change was made; provided as a dictionary with keys named `prechange`, `postchange` and `differences`.
+| Variable | Description |
+|----------|-------------|
+| `event` | The event type (`created`, `updated`, `deleted`). |
+| `model` | The Nautobot model triggering the event. |
+| `timestamp` | The event timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. |
+| `username` | The user who triggered the event. |
+| `request_id` | A unique request ID for correlation. |
+| `data` | A serialized representation of the object *after* the change. |
+| `snapshots` | Contains `prechange`, `postchange`, and `differences` snapshots. |
 
-### Default Request Body
+## Default Request Body
 
-If no body template is specified, the request body will be populated with a JSON object containing the context data. For example, a newly created Location might appear as follows:
+If no body template is provided, Nautobot sends a default JSON payload:
 
-```no-highlight
+```json
 {
     "event": "created",
-    "timestamp": "2023-02-14 12:34:56.000000+00:00",
+    "timestamp": "2023-02-14T12:34:56.000000+00:00",
     "model": "location",
     "username": "admin",
     "request_id": "fab0a4fb-52ba-4cb4-9756-4e6a3ac05332",
-    "data": {
-        "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-        "display": "Campus A",
-        "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-        "name": "Campus A",
-        "status": {
-            "display": "Active",
-            "id": "363a431c-c784-40b5-8513-758cafd174ad",
-            "url": "/api/extras/statuses/363a431c-c784-40b5-8513-758cafd174ad/",
-            "name": "Active",
-            "created": "2023-02-14T00:00:00Z",
-            "last_updated": "2023-02-14T19:40:13.216150Z"
-        },
-        ...
-    },
+    "data": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
     "snapshots": {
         "prechange": null,
-        "postchange": {
-            "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-            "asn": null,
-            "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-            "name": "Campus A",
-            ...
-        },
-        "differences": {
-            "removed": null,
-            "added": {
-                "id": "5e4f9a91-372b-46df-a50a-c26357475bee",
-                "asn": null,
-                "url": "/api/dcim/locations/5e4f9a91-372b-46df-a50a-c26357475bee/",
-                "name": "Campus A",
-                ...
-            }
-        }
+        "postchange": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" },
+        "differences": { "added": { "id": "5e4f9a91-372b-46df-a50a-c26357475bee", "name": "Campus A" } }
     }
 }
 ```
 
 ## Webhook Processing
 
-When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `celery worker` process and HTTP requests are sent to their respective destinations.
+When Nautobot detects a relevant change, it queues the webhook in Redis. This ensures that webhook processing does not delay the original request. A Celery worker then dequeues and sends the HTTP request to the specified receiver.
 
-A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
+A webhook request is considered successful if the receiver responds with a `2XX` status code. Failed requests can be retried manually via the admin UI.
 
-## Troubleshooting
+## Troubleshooting Webhooks
path: nautobot/docs/user-guide/platform-functionality/webhook.md
user: login: glennmatthews
body: Still needed.
created_at: 2025-03-20T19:45:49Z
author_association: CONTRIBUTOR

PR comments:
user: login: ssganesh035
created_at: 2025-03-17T19:20:36Z
body: Hi @HanlinMiao, I have added the 7030.documentation fragement. https://github.com/nautobot/nautobot/pull/7035

Hope it's good to go now!
author_association: CONTRIBUTOR
user: login: HanlinMiao
created_at: 2025-03-17T19:25:16Z
body: > Hi @HanlinMiao, I have added the 7030.documentation fragement. #7035
> 
> Hope it's good to go now!

Hi, @ssganesh035, sorry for not making it clear. But can you include the changelog fragment in this PR instead of making a separate one?
author_association: CONTRIBUTOR
user: login: ssganesh035
created_at: 2025-03-18T05:31:33Z
body: Done @HanlinMiao, kindly check now.
author_association: CONTRIBUTOR
user: login: ssganesh035
created_at: 2025-03-18T13:19:45Z
body: Hi @glennmatthews, thanks for the feedback. I have updated the suggestions and committed the same, kindly check and let me know.
author_association: CONTRIBUTOR