> For the complete documentation index, see [llms.txt](https://docs.panther.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.panther.com/~/changes/Dd8nx2iqd1Pp2OzWJaWk/alerts/destinations/servicenow-destination-custom-webhook.md).

# ServiceNow Destination (Custom Webhook)

Set up ServiceNow alerts using Panther's custom webhook option

## Overview&#x20;

With a simple Scripted Rest API configuration in the ServiceNow console, alerts fired from Panther can be mapped directly to new incidents. Leveraging Python detections and [our auxiliary functions](https://docs.panther.com/writing-detections/detection-auxiliary-functions) allows customers to dynamically create alerts with custom webhooks.

## How to configure ServiceNow to create tickets from Panther alerts

### Prerequisites

ServiceNow permissions to create a Scripted Rest API require a user with the **web\_service\_admin** role. The below ServiceNow references provide context on setting up these initial Scripted Rest API requirements:

* [How to Integrate Webhooks Into ServiceNow - Blog - ServiceNow Community](https://community.servicenow.com/community?id=community_blog\&sys_id=886d2a29dbd0dbc01dcaf3231f9619b0)
* [Scripted Rest APIs - ServiceNow Documentation](https://docs.servicenow.com/en-US/bundle/sandiego-application-development/page/integrate/custom-web-services/task/t_CreateAScriptedRESTService.html)

### Step 1: Create a Scripted Rest API in ServiceNow

1. In the ServiceNow console, click the **All** tab in the upper left-hand corner.&#x20;
2. Expand the **System Web Services** and **Scripted Web Services** navigations, then click on **Scripted REST APIs.**\ <img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Ff9R8KZxaAxt91H1uC8Cr%2Fimage.png?alt=media&amp;token=99a1a98c-1fb3-4176-99d6-f617ef972a1f" alt="In the ServiceNow console, the &#x22;All&#x22; tab is selected at the top. In the navigation menu, System Web Services is expanded, and Scripted REST APIs is highlighted." data-size="original">
3. Click **New** in the upper right-hand corner.&#x20;
4. Select a Name and an ID, for example, `Panther Incident Creation` and `panther_incident_creation`, respectively.\
   \
   ![The image shows the form to create a new Scripted REST Service in ServiceNow. It contains fields for Name, API ID, Protection Policy, Application, and API namespace. ](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FJGB2StgfJKFFGqE0agGA%2Fimage.png?alt=media\&token=9018007f-a91e-4542-9a68-e22132fe2a65)
5. Click **Submit**.
6. On the Scripted Rest API's page, search for the name you just created. Click the **hyperlinked name.**
7. Near the bottom of the page, click the **Resources tab.** Click the **New** button in the right-hand corner.
8. Fill out the Scripted REST Resource Alert page:
   * **Name:** Enter a descriptive name, e.g., `Panther_Alert`.  \
     ![The image shows the Scripted REST Resource configuration page in Service Now. The "Name" field has a red circle around it, and it is filled in with "Panther\_Alert".](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FyReSN1SPjhCIc3nS2Sd8%2FScripted%20REST%20ss%20name%20field.png?alt=media\&token=2fb5d442-aeb2-4241-bfa7-a86d3dfc5f48)
   * **HTTP method:** Select POST.
   * **Script:** Paste in the schema code below:

     * ```
       (function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

       	// prep the different fields 
       	var data = request.body.data;
       	var title = data.title;
       	var alert = JSON.stringify(data);
       	var alertContext = JSON.stringify(data.alertContext);
       	var severity = data.severity;
       	var link = data.link;
       	var runbook = data.runbook;
       	var type = data.type;
       	var alertId = data.alertId;
       	
       	var grIncident = new GlideRecord('incident');

       	grIncident.initialize();
       	
       	grIncident.setValue('short_description', title);
       	grIncident.setValue('description', alert );
       	grIncident.setValue('category', type);
       	grIncident.setValue('subcategory', alertId);
       	
       	//Map urgency to Panther severity
       	if (severity == "CRITICAL" || severity == "HIGH") {
       		grIncident.setValue('urgency','1');
       		grIncident.setValue('impact','1');
       	} else if (severity == "LOW" || severity == "MEDIUM") {
       		grIncident.setValue('urgency','2');
       	} else {
       		grIncident.setValue('urgency','3');
       	}
       	
       	//grIncident.insert();
       	var recResponse = grIncident.insert(handleResponse);

       	function handleResponse(recResponse, answer) {
       	// Answer will be the sys_id of the created record or null
       	alert('Newly created sys_id is - ' + answer + ' exists');
       	}

       	var url = gs.getProperty('glide.servlet.uri');

               //building the response of the API, this example returns the incident ID that got created above.
       	var body = {};
       	body.sys_id = recResponse;
       	body.link = url + "task.do?sys_id=" + recResponse;
       	response.setBody(body);
       	
       	//example test event from Panther when creating and testing destination integration
       	//{"id":"Test.Alert","createdAt":"2022-04-26T03:17:32.099054303Z","severity":"INFO","type":"RULE","link":"https://domain.runpanther.net","title":"This is a Test Alert","name":"Test Alert","alertId":"Test.Alert","alertContext":{},"description":"This is a Test Alert","runbook":"Stuck? Check out our docs: https://docs.runpanther.io","tags":["test"],"version":"abcdefg"}

       })(request, response);
       ```

     * Under the **Security** tab, uncheck the box next to **Requires authentication**.\
       ![The Security tab is displayed in ServiceNow. The "Requires Authentication" box is circled, and the box next to it is not checked.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fwj71HS3SgmHcqxbUpMkG%2Fservicenow%20authentication.png?alt=media\&token=bf1bfc7c-1790-41c2-ac20-83ab97c6ca3b)
9. Click **Submit**.

{% hint style="warning" %}
The schema provided above maps the alert payload from Panther to the relevant fields in the ServiceNow ticket. The [ServiceNow blog](https://community.servicenow.com/community?id=community_blog\&sys_id=886d2a29dbd0dbc01dcaf3231f9619b0) also provides a different example of receiving the POST payload. Each customer environment is different – select what works best for how the Alert payload is handled and parsed into your ServiceNow tickets.
{% endhint %}

### Step 2: Create a Custom Webhook integration in Panther

1. In the Panther Console, navigate to **Configure > Alert Destinations.**
2. Click **+Add your first Destination**.&#x20;
   * If you have already created Destinations, click **Create New** in the upper right side of the page to add a new Destination.
3. On the "Configure Your Webhook Destination page", fill out the form:
   * **Display Name:** Enter a descriptive name.
   * **Custom Webhook URL**: Enter your Custom Webhook forwarding URL.
     * Your webhook URL is in the following format: `https://yourdomain.service-now.com/<base_api_path>`&#x20;
     * This domain is shown in the "Rest API" section of your ServiceNow console.
   * **Severity**: Select the severity level of alerts to send to this Destination.&#x20;
   * **Alert Types**: Select the alert types to send to this Destination.&#x20;
   * **Log Type**: By default, we will send alerts from all log types. Specify log types here if you want to only send alerts from specific log types.\
     ![In the Panther Console, the "Configure your Custom Webhook Destination" page is displayed. It contains fields for Display Name, Custom Webhook URL, Severity, Alert Types, and Log Types.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FmD01HuNpwcnbnQXpyVps%2Fcustom%20webook%20destinations.png?alt=media\&token=b7ee3c3f-d44c-4f4c-955f-2ba50c31dbd0)
4. Click **Add Destination**.
5. Click **Send Test Alert** to make sure everything works correctly.
   * A test event should now exist in your ServiceNow Incidents table.\
     &#x20;![The image shows the Incidents Table in ServiceNow. There is a test event highlighted in the list.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FkqOIh6zxph47PU9lKVjZ%2Ftest%20event%20in%20ServiceNow.png?alt=media\&token=d21fb45f-abd6-4d39-a917-c379de8ab7e0)
6. Click **Finish Setup.**

### Example

Click the **Test Alert** button to generate an alert and send to ServiceNow; the payload of the alert is seen below:

```json
{"id":"Test.Alert","createdAt":"2022-04-26T03:17:32.099054303Z","severity":"INFO","type":"RULE","link":"https://domain.runpanther.net","title":"This is a Test Alert","name":"Test Alert","alertId":"Test.Alert","alertContext":{},"description":"This is a Test Alert","runbook":"Stuck? Check out our docs: https://docs.runpanther.io","tags":["test"],"version":"1"}
```

Once the alert is received by ServiceNow, an incident is created in ServiceNow Incident table:

<figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FCCsuuq6nUnoem41BZ8Tl%2Fimage.png?alt=media&amp;token=ede9720d-c561-465c-a4ae-a04b6596c9b9" alt="The Incident Table in ServiceNow contains a test alert."><figcaption></figcaption></figure>


---

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

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

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

```
GET https://docs.panther.com/~/changes/Dd8nx2iqd1Pp2OzWJaWk/alerts/destinations/servicenow-destination-custom-webhook.md?ask=<question>&goal=<endgoal>
```

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

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

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