Skip to main content

About ServiceNow

ServiceNow is an IT service management (ITSM) platform that manages tickets, incidents, change requests, and IT assets.

What the ServiceNow integration enables

CapabilityDescription
Ticket SyncNative bidirectional sync between Serval tickets and ServiceNow incidents
Service CatalogSync and order ServiceNow catalog items directly through Serval workflows
Knowledge BaseSync knowledge articles from ServiceNow directly into Serval for AI-powered assistance
Workflow AutomationBuild Serval workflows for incidents, problems, changes, catalog ordering, and more using ServiceNow APIs
Access ProfilesSync ServiceNow groups, roles, departments, companies, and locations for access control and provisioning

ServiceNow Configuration

This integration requires a dedicated service account with specific, limited permissions. Do not use a personal account or admin account. Following the principle of least privilege ensures security and auditability.

Prerequisites

Before configuring the ServiceNow integration in Serval, ensure you have:
  • Access to your ServiceNow instance as an administrator
  • Permissions to create users, roles, and ACLs
  • Knowledge of your ServiceNow instance name

Step 1: Create a Dedicated Integration User

1

Navigate to User Administration

  1. Log in to your ServiceNow instance as an administrator
  2. In the application navigator search bar, type “Users” and select User Administration → Users
  3. Click New to create a new user
2

Configure User Details

Fill in the required user information:
FieldValue
User IDserval.integration
First nameServal
Last nameIntegration
Active✅ Checked
Web service access only✅ Checked (recommended for API-only accounts)
Internal Integration User✅ Checked (if available in your ServiceNow version)
Photo (Optional)Download the Serval logo then select it from your downloads
Setting “Web service access only” ensures this account cannot be used for interactive login, improving security.
Click Submit to create the user.
3

Set the User Password

  1. On the Users page, search for the user you just created and click on it
  2. Click Set Password
  3. Click Generate Password
  4. Important: Click the Copy button to copy the password and save it securely
Save this password immediately — you will not be able to view it again. You’ll need it when configuring Serval.
  1. Click Submit

Step 2: Create a Custom Role for Serval

Creating a custom role with granular permissions is the recommended approach for production environments. This follows the principle of least privilege and provides better security than using out-of-the-box roles like itil or admin.
1

Create the Custom Role

  1. In the navigator, search for “Roles” and select User Administration → Roles
  2. Click New
  3. Fill in the role details:
FieldValue
Namex_serval_integration
DescriptionCustom role for Serval integration with least-privilege API access
  1. Click Submit
2

Add Base Roles

Open the role you just created and scroll down to the Contains Roles related list. Add the following base roles:
RolePurpose
rest_api_explorerEnables REST API access
personalize_choicesAllows reading sys_choice values
personalize_dictionaryAllows reading sys_dictionary for field definitions
These base roles provide the foundational REST API capabilities. We will add granular table access via ACLs in the next step.

Step 3: Configure Table Access via ACLs

Serval requires specific read/write access to various ServiceNow tables. You’ll create Access Control List (ACL) rules to grant only the necessary permissions.
Serval uses the following ServiceNow APIs, which may require specific plugins to be active on your instance:
  • Table API (/api/now/table) — Active by default on all instances
  • Service Catalog API (/api/sn_sc/servicecatalog) — Requires the Service Catalog plugin (active by default)
  • Change Management REST API (/api/sn_chg_rest/change) — Requires the Change Management - REST API plugin (com.snc.change_management.rest_api)
  • Attachment API (/api/now/attachment) — Active by default on all instances
The following tables require access:

Incident Management Tables

TableReadCreateWritePurpose
incidentIncident records (all standard fields)
sys_journal_fieldComments and work notes

Service Catalog Tables

TableReadCreateWritePurpose
sc_cat_itemCatalog item details
sc_categoryCatalog categories
sc_requestService requests
sc_req_itemRequested items
item_option_newCatalog item variable definitions
io_set_itemVariable set to catalog item mapping
question_choiceChoices for select-type catalog variables
sys_attachmentFile attachment uploads for requested items

Configuration Tables (Read-Only)

TableReadCreateWritePurpose
sys_userUser lookup for assignment
sys_user_groupAssignment group lookup
sys_choiceField dropdown values
sys_dictionaryField definitions
cmdb_ci_serviceBusiness services

Knowledge Base Tables (Read-Only)

TableReadCreateWritePurpose
kb_knowledge_baseKnowledge base metadata
kb_categoryKnowledge categories
kb_knowledgeKnowledge articles

User Criteria Tables (Read-Only)

These tables are used to determine which users have access to knowledge articles and catalog items.
TableReadCreateWritePurpose
user_criteriaUser criteria definitions (users, groups, companies, etc.)
kb_uc_can_read_mtomKnowledge article access - users who CAN read
kb_uc_cannot_read_mtomKnowledge article access - users who CANNOT read
sc_cat_item_user_criteria_mtomCatalog item access - users who CAN access
sc_cat_item_user_criteria_no_mtomCatalog item access - users who CANNOT access

Change Management Tables

These tables are required for change request workflows.
TableReadCreateWritePurpose
change_requestChange request records
sysapproval_approverChange request approval records
Creating change requests uses the Change Management REST API (/api/sn_chg_rest/change), which requires the Change Management - REST API plugin to be active on your ServiceNow instance. This plugin is active by default on most instances.

Problem Management Tables

TableReadCreateWritePurpose
problemProblem records

Access Management & Resource Sync Tables

These tables are required if using Serval’s access profile capabilities for syncing organizational resources and provisioning/deprovisioning users.
If you are not using access profiles, you can skip these ACLs. The sys_user and sys_user_group tables listed above under Configuration Tables still require read access for basic functionality regardless.
TableReadCreateWriteDeletePurpose
sys_userWrite access for department assignment (read access already listed above)
sys_user_grmemberGroup membership provisioning and deprovisioning
sys_user_roleRole definitions for resource sync
sys_user_has_roleRole assignment provisioning and deprovisioning
core_companyCompany records for resource sync
cmn_departmentDepartment records for resource sync
cmn_locationLocation records for resource sync
cmn_cost_centerCost center records for resource sync

Step 4: Assign the Custom Role to the Integration User

1

Open the User Record

  1. Navigate to User Administration → Users
  2. Find and open the serval.integration user
2

Add the Custom Role

  1. Scroll down to the Roles related list
  2. Click Edit
  3. Add the x_serval_integration role (or the OOB roles if you chose that approach)
  4. Click Save

Step 5 (Optional): Verify API Access

This step is optional but recommended to verify your configuration before connecting to Serval. If you encounter issues connecting, use these methods to troubleshoot.
1

Test with REST API Explorer

  1. In the navigator, search for “REST API Explorer”
  2. In the Namespace dropdown, select now
  3. In the API Name dropdown, select Table API
  4. Click Send to test a simple query
If you see a successful response with data, the API access is working correctly.
2

Test with cURL (Optional)

You can also test from the command line:
curl -X GET \
  'https://YOUR_INSTANCE.service-now.com/api/now/table/incident?sysparm_limit=1' \
  -H 'Accept: application/json' \
  -u 'serval.integration:YOUR_PASSWORD'
Replace YOUR_INSTANCE and YOUR_PASSWORD with your actual values.

Step 6: Identify Your ServiceNow Instance

Your ServiceNow instance name can be found in your ServiceNow URL:
  • If your ServiceNow URL is https://mycompany.service-now.com, then:
    • Instance Name: mycompany
The instance name is the subdomain portion of your ServiceNow URL.

Serval Configuration

Once you have created the integration user with appropriate permissions, follow these steps to configure the integration in Serval:
1

Navigate to ServiceNow App

  1. In Serval, go to Apps → Available → ServiceNow → Connect
  2. The ServiceNow configuration form will appear
2

Enter Configuration Details

Fill in the following fields with the information from your ServiceNow setup:
FieldDescriptionExample
Instance NameYour ServiceNow instance identifiermycompany
UsernameThe username of your integration userserval.integration
PasswordThe password for your integration useryour_secure_password
3

Test the Connection

  1. Navigate to the API Integration tab
  2. Click Run on the healthchecks to verify that Serval can successfully authenticate with your ServiceNow instance
Need additional help with your ServiceNow integration? Contact support@serval.com for technical assistance or advanced configuration questions.

Real-Time Comment Sync via Webhook (Optional)

By default, Serval polls your ServiceNow instance to sync comments. For faster, near-instant comment delivery, you can configure a Business Rule that pushes new comments to Serval via webhook. This applies to comments on Incidents and Catalog Request Items that were created by the Serval integration.
This requires a single Business Rule on the sys_journal_field table. No ServiceNow plugins, store apps, or additional licensing are required.

How it works

When a comment is added to a Serval-managed record, an async insert Business Rule fires on the sys_journal_field table. The rule verifies the parent record was opened by the Serval service account, constructs a JSON payload, and sends it asynchronously to the Serval webhook. Serval processes the event and delivers the comment to the relevant conversation in real time.

Webhook endpoint

PropertyValue
URLhttps://svwebhook.api.serval.com/servicenow/new-comment
MethodPOST
Content-Typeapplication/json
AuthenticationToken via X-Serval-Webhook-Token header
The Business Rule sends a JSON body with this structure:
{
  "instance_url":  "https://customer.service-now.com",
  "table":         "incident",
  "record_sys_id": "a1b2c3d4e5f6...",
  "number":        "INC0012345",
  "comment": {
    "sys_id":          "f6e5d4c3b2a1...",
    "element":         "comments",
    "value":           "The comment body text",
    "sys_created_by":  "jane.doe",
    "sys_created_on":  "2026-03-13 14:30:00"
  }
}
FieldTypeDescription
instance_urlstringYour ServiceNow instance URL
tablestringSource table: incident, sn_hr_core_case, or sc_req_item
record_sys_idstringsys_id of the parent record
numberstringRecord number, e.g. INC0012345, HRC0001234, RITM0056789
comment.sys_idstringsys_id of the journal entry
comment.elementstringcomments or work_notes
comment.valuestringThe comment body text
comment.sys_created_bystringuser_name of the commenter
comment.sys_created_onstringServiceNow timestamp

Create the Business Rule

1

Navigate to Business Rules

In ServiceNow, go to System Definition → Business Rules and click New.
2

Configure the rule settings

Set the following fields:
FieldValue
NameServal – Sync Comment to Webhook
Tablesys_journal_field
AdvancedChecked
Whenasync
InsertChecked
UpdateUnchecked
DeleteUnchecked
QueryUnchecked
ServiceNow Business Rule configuration showing the When to run tab with async timing, Insert checked, and the sys_journal_field table selected
3

Add the script

Switch to the Advanced tab and paste the following script:
ServiceNow Business Rule Advanced tab showing the webhook script in the script editor
(function executeRule(current, previous /*null when async*/) {

    var tableName   = current.getValue('name');
    var elementType = current.getValue('element');

    // Validate: only Serval-managed records.
    // Replace 'serval.integration' with the user_name of your
    // Serval service account if it differs.
    var SERVAL_USER = 'serval.integration';

    var recordSysId = current.getValue('element_id');
    var parentRecord = new GlideRecord(tableName);
    if (!parentRecord.get(recordSysId)) {
        gs.warn('Serval webhook: parent record not found: '
                + tableName + '/' + recordSysId);
        return;
    }

    var openedBy = parentRecord.opened_by.user_name.toString();
    if (openedBy !== SERVAL_USER) {
        return;
    }

    // Build payload
    var instanceName = gs.getProperty('instance_name');
    var instanceUrl  = 'https://' + instanceName + '.service-now.com';

    var payload = {
        instance_url:  instanceUrl,
        table:         tableName,
        record_sys_id: recordSysId,
        number:        parentRecord.getValue('number'),
        comment: {
            sys_id:         current.getUniqueValue(),
            element:        elementType,
            value:          current.getValue('value'),
            sys_created_by: current.getValue('sys_created_by'),
            sys_created_on: current.getValue('sys_created_on')
        }
    };

    // Configuration
    // Replace the token value with the token provided by Serval.
    // For production, store this in a System Property
    // (e.g., x_serval.webhook_token) and retrieve it via
    // gs.getProperty('x_serval.webhook_token').
    var SERVAL_WEBHOOK_URL   = 'https://svwebhook.api.serval.com/servicenow/new-comment';
    var SERVAL_WEBHOOK_TOKEN = '<TOKEN_PROVIDED_BY_SERVAL>';

    try {
        var request = new sn_ws.RESTMessageV2();
        request.setEndpoint(SERVAL_WEBHOOK_URL);
        request.setHttpMethod('POST');
        request.setRequestHeader('Content-Type', 'application/json');
        request.setRequestHeader('X-Serval-Webhook-Token', SERVAL_WEBHOOK_TOKEN);
        request.setRequestBody(JSON.stringify(payload));

        // Run asynchronously so we don't block the user's transaction
        request.setEccParameter('skip_sensor', 'true');

        var response = request.executeAsync();

        gs.info('Serval webhook: sent ' + elementType + ' event for '
            + tableName + '/' + parentRecord.getValue('number')
            + ' (async)');
    } catch (e) {
        gs.error('Serval webhook: failed to send event: ' + e.message);
    }

})(current, previous);
The script references serval.integration as the Serval service account user_name. This must match the user_name of the service account provisioned in your instance. If your team chose a different name during onboarding, update the SERVAL_USER variable accordingly.
4

Save the Business Rule

Click Submit to save the rule. Comment sync will begin working immediately for Serval-managed records.