> ## Documentation Index
> Fetch the complete documentation index at: https://docs.2501.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Set up real-time webhook notifications from ServiceNow

Webhooks allow ServiceNow to notify 2501 immediately when an incident or change request is created or updated, instead of waiting for the next polling cycle. Each webhook registration generates a unique URL and shared secret that you configure on the ServiceNow side.

## Creating a Webhook

Create a webhook through the [API](https://docs.2501.ai/0.19/api/overview.md), with an API key that reaches the gateway's organization:

```bash theme={null}
curl -X POST "https://<your-command-center-host>/api/v1/webhooks" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "servicenow",
    "org_id": "org_460b541c-...",
    "gateway_id": "gtw_a1b2c3d4-...",
    "event_type": "incident",
    "name": "prod-incidents"
  }'
```

### Parameters

| Field | Required | Description |
| - | - | - |
| `source_type` | Yes | `servicenow` |
| `org_id` | Yes | The organization of the gateway |
| `gateway_id` | Yes | The ServiceNow gateway that receives the tickets. Its metadata must set `servicenow_assigned_group_id` |
| `event_type` | Yes | The ServiceNow table to watch: `incident` or `change_request` |
| `name` | Yes | A name for the webhook, 40 characters at most, without `^`. The Business Rule is named `2501_wh_<environment>_<name>` in snake case, from the gateway's `environment` metadata, or `2501_wh_<name>` without one, cut at 40 characters |
| `servicenow_admin` | No | `{ "username": ..., "password": ... }` of a ServiceNow account allowed to create Business Rules. When present, 2501 creates the Business Rule itself: see [Let 2501 create the Business Rule](#let-2501-create-the-business-rule) |

The response carries the ingest `url`, the shared `secret`, and the `business_rule` to add to ServiceNow, with `business_rule_created: false`. The secret is shown once: later reads never return it.

```json theme={null}
{
  "id": "whk_e5f6a7b8-...",
  "name": "prod-incidents",
  "source_type": "servicenow",
  "event_type": "incident",
  "gateway_id": "gtw_a1b2c3d4-...",
  "url": "https://cmd.example.com/api/webhooks/ingest/4f8a2c1e9b3d7a0f6e5c8d2b",
  "secret": "a1b2c3d4...",
  "business_rule": {
    "name": "2501_wh_prod_incidents",
    "collection": "incident",
    "active": true,
    "advanced": true,
    "when": "after",
    "action_insert": true,
    "action_update": true,
    "filter_condition": "assignment_group=<your group>^active=true",
    "script": "(function executeRule(current, previous) { ... })(current, previous);",
    "order": 100
  }
}
```

## Configuring ServiceNow

After creating a webhook, configure ServiceNow to send events to it using a **Business Rule**.

### Let 2501 create the Business Rule

Add `servicenow_admin` to the create request, with a ServiceNow account allowed to create Business Rules:

```json theme={null}
{
  "source_type": "servicenow",
  "org_id": "org_460b541c-...",
  "gateway_id": "gtw_a1b2c3d4-...",
  "event_type": "incident",
  "name": "prod-incidents",
  "servicenow_admin": { "username": "<admin-user>", "password": "<password>" }
}
```

The engine creates the rule in the ServiceNow instance of the gateway's organization (its `servicenow_api_url` credential), through the installation's outbound proxy and with the gateway's `skip_tls_verify` setting. The account is used for this request only: 2501 does not store it, log it, or return it. The response has `business_rule_created: true` and no `business_rule`.

* When a Business Rule with the webhook's rule name already exists, the request fails with `409` and no webhook is created. Delete the rule in ServiceNow, or pick another name.
* When ServiceNow refuses the request, for example because the admin password is wrong, the request fails with `400` and no webhook is created.
* When ServiceNow does not answer or answers with a server error (`5xx`), the request fails with `502`. ServiceNow may have saved the rule before the failure, so 2501 keeps the webhook and the error names it: delete it with the same `servicenow_admin` account (see [Listing and Deleting Webhooks](#listing-and-deleting-webhooks)), which removes the rule too when it exists.

### Send the rule yourself

The quickest way is to send the `business_rule` object from the response to your instance's Table API, with a ServiceNow account allowed to create Business Rules:

```bash theme={null}
curl -X POST "https://<your-instance>.service-now.com/api/now/table/sys_script" \
  -u "<admin-user>:<password>" \
  -H "Content-Type: application/json" \
  -d "$BUSINESS_RULE_JSON"
```

### Business Rule by hand

1. In ServiceNow, navigate to **System Definition** > **Business Rules**
2. Click **New**
3. Configure:
   * **Name**: a descriptive name (e.g., `2501 Webhook - Incidents`)
   * **Table**: `incident` (or the table matching your `event_type`)
   * **When**: `after`
   * **Insert**: checked
   * **Update**: checked
4. Check **Advanced**
5. Paste the `script` from the response into the **Script** field
6. Optionally add a **Filter Condition** to scope which incidents trigger the webhook (e.g., `Assignment group is <your group>`)
7. Click **Submit**

> [!NOTE]
>
> Both the `incident` and `change_request` tables are supported. A gateway that handles incidents and changes uses two webhooks, one per table, each with its own Business Rule. For how change requests are picked up and executed, see [Change Requests](https://docs.2501.ai/0.19/core-concepts/gateways.md#change-requests).

## Splunk alerts

Splunk can send alerts to 2501 for [Observability](https://docs.2501.ai/0.19/core-concepts/observability.md). Each organization has its own signal key.

1. Turn on the `enableObservability` feature toggle and restart the engine.
2. Create the organization's signal key:

   ```bash theme={null}
   curl -X POST "https://<your-command-center-host>/api/v1/webhooks" \
     -H "Authorization: Bearer $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"source_type": "splunk", "org_id": "<org-id>", "name": "splunk"}'
   ```

   The response's `key` is shown once. Store it in Splunk; 2501 keeps only a one-way copy.
3. In Splunk, add a webhook alert action that posts to `https://<your-command-center>/api/v1/signals` with the header `Authorization: Bearer <signal key>`.

## Listing and Deleting Webhooks

```bash theme={null}
# The organization's webhooks; add &gateway_id=<id> to narrow to one gateway
curl "https://<your-command-center-host>/api/v1/webhooks?org_id=<org-id>" \
  -H "Authorization: Bearer $API_KEY"

curl -X DELETE "https://<your-command-center-host>/api/v1/webhooks/whk_e5f6a7b8-..." \
  -H "Authorization: Bearer $API_KEY"
```

This removes the webhook registration from 2501. Deactivate or delete the corresponding Business Rule in ServiceNow too, or let 2501 delete it by sending the same `servicenow_admin` account in the body:

```bash theme={null}
curl -X DELETE "https://<your-command-center-host>/api/v1/webhooks/whk_e5f6a7b8-..." \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"servicenow_admin": {"username": "<admin-user>", "password": "<password>"}}'
```

2501 deletes the Business Rule it named when it created the webhook, so a later change to the gateway's `environment` does not lose it, then the webhook. The response's `business_rule_deleted` says whether a rule was found and deleted. When ServiceNow refuses the request, for example because the admin password is wrong, it fails with `400`; when ServiceNow does not answer or answers with a server error, it fails with `502`. The webhook stays in both cases. When the rule with that name does not send to this webhook, 2501 leaves it in ServiceNow and the request fails with `409`; the webhook stays.

## Network Requirements

The ServiceNow instance must be able to reach your Command Center's URL over HTTPS. The webhook endpoint is:

```
POST https://<your-command-center>/api/webhooks/ingest/<path>
```

## How It Works

1. ServiceNow fires the Business Rule when a record (incident or change request) is created or updated
2. The script sends a POST request with the record's `sys_id` to the webhook URL
3. Command Center proxies the request to the engine
4. The engine validates the shared secret, then enqueues the ticket for processing
5. The engine fetches the full record details from ServiceNow and processes it through the [gateway](https://docs.2501.ai/0.19/core-concepts/gateways.md) pipeline

Webhooks are complemented by a polling reconciliation that runs every \~2 minutes, ensuring no records are missed even if a webhook delivery fails.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.