0% found this document useful (0 votes)
2 views18 pages

Module 15 REST SOAP Integrations Complete Guide

The document serves as a comprehensive guide for ServiceNow REST and SOAP integrations, detailing both outbound and inbound integration methods with real-world examples involving systems like Jira, Slack, and Salesforce. It covers integration architecture, authentication methods, and provides step-by-step instructions for setting up various integrations. Additionally, it includes expert Q&A to assist ServiceNow professionals with 6+ years of experience.

Uploaded by

sreenivaskola
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views18 pages

Module 15 REST SOAP Integrations Complete Guide

The document serves as a comprehensive guide for ServiceNow REST and SOAP integrations, detailing both outbound and inbound integration methods with real-world examples involving systems like Jira, Slack, and Salesforce. It covers integration architecture, authentication methods, and provides step-by-step instructions for setting up various integrations. Additionally, it includes expert Q&A to assist ServiceNow professionals with 6+ years of experience.

Uploaded by

sreenivaskola
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

ServiceNow REST & SOAP

Integrations
Complete End-to-End Expert Guide + Interview Q&A
OUTBOUND: ServiceNow calling external systems (REST Messages, OAuth,
SOAP, IntegrationHub) with Jira/Salesforce/Slack real examples.
INBOUND: External systems calling ServiceNow (Table API, Scripted REST,
Webhooks) with full end-to-end working examples + 15 expert Q&A.

For ServiceNow Professionals with 6+ Years Experience


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 2

PART 1 — Integration Architecture Overview

1. ServiceNow integration landscape


Direction What it means Methods available

OUTBOUND ServiceNow CALLS an external system REST Message, SOAP Message, IntegrationHub
Spoke, Action Designer

INBOUND External system CALLS ServiceNow Table API, Scripted REST API, Import Set REST API,
SOAP Web Service

BIDIRECTIONAL Both directions — true sync Combination of outbound + inbound endpoints with
reconciliation logic

EVENT-DRIVEN ServiceNow publishes events; external Outbound webhook from Flow Designer / Business
subscribes Rule

Golden rule: always prefer IntegrationHub spokes over raw REST Messages for supported systems

If a pre-built Spoke exists (Jira, Slack, Salesforce, GitHub, AWS, Teams, PagerDuty):

-> USE THE SPOKE. You get: auth handling, error management, version updates,

and a drag-droppable action that non-developers can use in Flow Designer.

If no spoke exists or you need fine-grained control:

-> Build a REST Message with proper auth, error handling, and retry logic.

Then optionally wrap it in a custom Action Designer action for reusability.

Never use Business Rules for synchronous REST calls to external APIs.

-> Use Async Business Rules or Flow Designer — never block user saves with external calls.

2. Authentication methods — complete reference


Auth method Use case Where configured in ServiceNow

Basic Auth Simple user:password — dev/test environments REST Message > HTTP Request > Auth Type
ONLY (never production) = Basic

OAuth 2.0 Client Server-to-server M2M auth — most common for System OAuth > Application Registry
Credentials production

OAuth 2.0 Authorization User-delegated access — rare in integrations System OAuth > Application Registry
Code

API Key (header) External system issues a key — add as custom REST Message > HTTP Header param
HTTP header

Bearer Token (static) Long-lived token — less secure, avoid if OAuth REST Message > HTTP Header: Authorization
available

Mutual TLS (mTLS) Certificate-based — highest security, often Instance SSL certificates + REST Message
required for banks/gov cert config

HMAC Signature Sign request body with shared secret — common Custom script in before-send hook of REST
in webhooks Message

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 3

PART 2 — OUTBOUND: ServiceNow Calls External Systems

3. Real-world Example A — ServiceNow → Jira: Create a Jira Issue when a


Change Request is approved
Scenario: Your DevOps team works in Jira. When IT approves a Change Request in ServiceNow, a corresponding Jira ticket
must be auto-created in the ITOPS project so the DevOps team can track implementation.

Complete end-to-end: Change approved in SN -> Jira issue created

■■■■ STEP 1: Create Jira OAuth App (done in Jira) ■■■■

1. Jira Cloud > Settings > Developer Console > Create App

2. Name: 'ServiceNow Integration'

3. Permissions: Write Issues in ITOPS project

4. OAuth 2.0 (3LO) > Get Client ID and Client Secret

5. Redirect URL: [Link]

■■■■ STEP 2: Register OAuth in ServiceNow ■■■■

Navigate: System OAuth > Application Registry > New

Name: 'Jira Cloud OAuth'

Client ID: [from Jira] | Client Secret: [from Jira]

Token URL: [Link]

Auth URL: [Link]

Scope: read:jira-work write:jira-work

Click 'Get OAuth Token' -> login to Jira to authorize

■■■■ STEP 3: Create REST Message ■■■■

Navigate: System Web Services > Outbound > REST Messages > New

Name: 'Jira Cloud API'

Endpoint: [Link]

Auth Type: OAuth 2.0 | OAuth Profile: 'Jira Cloud OAuth'

HTTP Method > New:

Name: 'create_issue' | HTTP Method: POST

Relative URL: /issue

Content-Type: application/json

Request body:

{"fields":{"project":{"key":"ITOPS"},"summary":"${summary}",

"description":{"type":"doc","version":1,"content":[

{"type":"paragraph","content":[{"type":"text","text":"${description}"}]}]},

"issuetype":{"name":"Task"},"priority":{"name":"${priority}"}}}

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 4

■■■■ STEP 4: Business Rule — fires when Change is approved ■■■■

Table: change_request | When: After | Update: true

Condition: [Link] == '3' && [Link]('3')

(State 3 = Authorize/Approved in Change workflow)

Script (Async Business Rule to not block user save):

var rm = new sn_ws.RESTMessageV2('Jira Cloud API', 'create_issue');

[Link]('summary',

[Link] + ': ' + current.short_description);

[Link]('description',

'Change: ' + [Link] +

'\nRisk: ' + [Link]('risk') +

'\nScheduled: ' + [Link]('start_date') +

'\nServiceNow link: ' +

[Link]('[Link]') + [Link](true));

[Link]('priority',

[Link] == '1' ? 'High' : 'Medium');

var response = [Link]();

if ([Link]() == 201) {

var body = [Link]([Link]());

current.u_jira_key = [Link];

current.work_notes = 'Jira issue created: ' + [Link] +

' | ' + '[Link] + [Link];

[Link]();

} else {

[Link]('Jira create failed: ' + [Link]() +

' | ' + [Link]());

4. Real-world Example B — ServiceNow → Slack: Notify #p1-alerts when a P1


Incident is created
// ■■ SETUP: Create Slack Incoming Webhook ■■■■■■■■■■■■■■■■■■■■■■■■■■

// 1. Slack App Directory > Create a Slack App > Incoming Webhooks > ON

// 2. Add Webhook to workspace > copy webhook URL

// 3. Store URL as sys_property: [Link] (more secure than hardcoding)

// ■■ REST Message config ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

// Name: 'Slack Incoming Webhook'

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 5

// Endpoint: ${webhook_url} (variable so URL comes from the script)

// Auth Type: No Authentication (Slack webhook URL IS the authentication)

// HTTP Method: POST | Content-Type: application/json

// Body: { 'text': '${message}' }

// ■■ Business Rule: After Insert on Incident ■■■■■■■■■■■■■■■■■■■■■■■

// Condition: [Link] == '1' (P1 only)

// When: After | Insert: true

// Type: ASYNC (don't block the incident save)

(function executeRule(current, previous) {

var webhookUrl = [Link]('[Link]');

if (!webhookUrl) {

[Link]('Slack webhook URL not configured');

return;

var incLink = [Link]('[Link]') + [Link](true);

var payload = {

blocks: [

type: 'header',

text: { type: 'plain_text',

text: ':rotating_light: P1 INCIDENT: ' + [Link] }

},

type: 'section',

fields: [

{ type: 'mrkdwn',

text: '*Summary:*\n' + current.short_description },

{ type: 'mrkdwn',

text: '*Assigned to:*\n' +

current.assignment_group.getDisplayValue() },

{ type: 'mrkdwn',

text: '*Caller:*\n' + current.caller_id.getDisplayValue() },

{ type: 'mrkdwn',

text: '*Opened:*\n' + [Link]('opened_at') }

},

type: 'actions',

elements: [

{ type: 'button', style: 'danger',

text: { type: 'plain_text', text: 'View in ServiceNow' },

url: incLink }

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 6

};

var rm = new sn_ws.RESTMessageV2();

[Link](webhookUrl);

[Link]('POST');

[Link]('Content-Type', 'application/json');

[Link]([Link](payload));

[Link](10000);

var response = [Link]();

if ([Link]() != 200) {

[Link]('Slack P1 notification failed: ' + [Link]());

})(current, previous);

5. Real-world Example C — ServiceNow → Salesforce: Sync Account data via


OAuth
// ■■ OAuth setup (System OAuth > Application Registry) ■■■■■■■■■■■■

// Name: Salesforce Prod OAuth

// Client ID/Secret: from Salesforce Connected App

// Token URL: [Link]

// Grant type: client_credentials (server-to-server)

// ■■ Script Include: SalesforceSync ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

var SalesforceSync = [Link]();

[Link] = {

initialize: function() {

[Link] = [Link]('[Link]');

},

// Upsert a customer account to Salesforce

syncAccount: function(accountSysId) {

var acct = new GlideRecord('customer_account');

if (![Link](accountSysId)) return false;

var payload = {

Name: [Link]('name'),

Phone: [Link]('phone'),

Website: [Link]('website'),

ServiceNow_ID__c: accountSysId // custom field in SF

};

// Use Salesforce Composite API upsert by ServiceNow_ID__c

var rm = new sn_ws.RESTMessageV2();

[Link]([Link] +

'/services/data/v58.0/sobjects/Account/ServiceNow_ID__c/' +

accountSysId);

[Link]('PATCH'); // PATCH = upsert in Salesforce

[Link]('Content-Type', 'application/json');

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 7

[Link]('Salesforce Prod OAuth Profile', '');

[Link]([Link](payload));

try {

var resp = [Link]();

// 200 = updated, 201 = created, 204 = updated (no body)

if ([200, 201, 204].indexOf([Link]()) != -1) {

[Link]('SF sync OK for account: ' + [Link]('name'));

return true;

[Link]('SF sync failed: ' + [Link]() +

' | ' + [Link]());

return false;

} catch(e) {

[Link]('SF sync exception: ' + [Link]());

return false;

},

type: 'SalesforceSync'

};

// Called from Async Business Rule on customer_account update:

var sf = new SalesforceSync();

[Link]([Link]());

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 8

PART 3 — INBOUND: External Systems Call ServiceNow

6. ServiceNow out-of-the-box REST APIs — use without any configuration


API Base path What it does

Table API GET/POST/PUT/PATCH/DELETE Full CRUD on any table — most commonly used
/api/now/table/{tableName}

Aggregate API GET /api/now/stats/{tableName} COUNT, SUM, AVG on table data with filters

Attachment API POST /api/now/attachment/file Upload attachments to records

Import Set API POST /api/now/import/{stagingTable} Push rows directly into an Import Set staging table

CI Relationship API GET Get all CI relationships for a specific CI


/api/now/cmdb/instance/{sys_id}/relationship

Identity API GET /api/now/identity Get info about the authenticated user

UI Action API POST /api/now/ui_action/{action_name} Execute a server-side UI Action via REST

7. Real-world Example D — External system → ServiceNow Table API: Create an


incident
Scenario: Your monitoring platform (Dynatrace, Datadog, custom tool) detects an issue and needs to create a ServiceNow
Incident via REST API — without any ServiceNow plugin, just standard HTTP calls.

// ■■ From the EXTERNAL SYSTEM (any language) ■■■■■■■■■■■■■■■■■■■■■■■

// This is what the external caller sends to ServiceNow:

POST [Link]

Headers:

Content-Type: application/json

Accept: application/json

Authorization: Basic base64('sn_api_user:SecurePassword123!')

// OR: Authorization: Bearer <oauth_access_token>

Body:

"short_description": "Production database slow - response time > 30s",

"description": "Dynatrace detected: avg response time 31,450ms on DB-PROD-01",

"category": "database",

"priority": "1",

"impact": "1",

"urgency": "1",

"assignment_group": "ca2e8e1c3b1234567890abcd1234ef56",

// sys_id of group — or use setDisplayValue workaround:

"sysparm_fields": "number,sys_id,state,assignment_group"

// Only return these fields in response

// ServiceNow Response (HTTP 201 Created):

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 9

"result": {

"number": "INC0045678",

"sys_id": "abc123def456789...",

"state": { "display_value": "New", "value": "1" },

"assignment_group": {

"display_value": "Database Team",

"link": "[Link]

"value": "ca2e8e1c..."

// ■■ Query the created incident (GET) ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

GET /api/now/table/incident?

sysparm_query=number%3DINC0045678

&sysparm_fields=number,state,priority,assigned_to

&sysparm_limit=1

// ■■ Update the incident (PATCH) ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

PATCH /api/now/table/incident/{sys_id}

Body: { "state": "6", "close_notes": "Fixed by DBA team - index rebuilt" }

// ■■ Table API filter operators ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

// Use encoded queries in sysparm_query:

// priority=1 -> priority equals 1

// priority=1^state=2 -> priority=1 AND state=2

// priority=1^ORpriority=2 -> priority=1 OR priority=2

// opened_atONToday@javascript:[Link]()@javascript:[Link]()

// assignment_groupIN<sys_id1>,<sys_id2>

8. Real-world Example E — Build a Scripted REST API for Jira to call back into
ServiceNow
Scenario: When a Jira issue is resolved, Jira sends a webhook to ServiceNow to automatically close the linked Change
Request. You build a custom endpoint ServiceNow exposes specifically for Jira.

Complete Scripted REST API: /api/x_myco/jira_callback/change_resolved

■■■■ STEP 1: Create the API container ■■■■

Navigate: System Web Services > Scripted REST APIs > New

Name: 'Jira Callback API' | API ID: jira_callback

Namespace: x_myco

Base path auto-generated: /api/x_myco/jira_callback

■■■■ STEP 2: Add a resource ■■■■

Resources tab > New:

Name: 'Change Resolved' | HTTP Method: POST

Relative path: /change_resolved

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 10

Full URL: POST /api/x_myco/jira_callback/change_resolved

Requires authentication: true | Required roles: jira_integration

■■■■ STEP 3: Resource script ■■■■

(function process(request, response) {

// Validate the request has a body

if (![Link] || ![Link]) {

[Link](400);

[Link]({ error: 'Empty request body' });

return;

var payload;

try {

payload = [Link]([Link]);

} catch(e) {

[Link](400);

[Link]({ error: 'Invalid JSON body' });

return;

// Jira sends: { issue: { key: 'ITOPS-123', fields: { status: 'Done' } } }

var jiraKey = [Link] && [Link];

if (!jiraKey) {

[Link](422);

[Link]({ error: 'Missing [Link] in payload' });

return;

// Find the linked ServiceNow Change Request

var cr = new GlideRecord('change_request');

[Link]('u_jira_key', jiraKey);

[Link]('state', '!=', '3'); // not already closed

[Link]();

if (![Link]()) {

[Link](404);

[Link]({ error: 'No active Change found for Jira key: ' + jiraKey });

return;

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 11

// Close the Change Request

[Link] = '3'; // Closed

cr.close_notes = 'Auto-closed: Jira issue ' + jiraKey + ' resolved';

cr.work_notes = 'Jira callback received at ' + [Link]() +

'. Jira status: ' + ([Link] || 'Done');

[Link]();

[Link](200);

[Link]({

status: 'success',

change_number: [Link]('number'),

message: 'Change closed successfully'

});

})(request, response);

■■■■ STEP 4: Create a dedicated service account for Jira ■■■■

1. Create sys_user: jira_sn_integration

2. Assign role: jira_integration (custom role with write on change_request)

3. Give Jira this user's credentials OR set up OAuth 2.0

4. In Jira: Automation > When issue resolved > Send webhook to SN endpoint

URL: [Link]

Auth: Basic <jira_sn_integration credentials>

9. SOAP Integration — legacy systems deep dive


SOAP (Simple Object Access Protocol) is an XML-based web service protocol used heavily in legacy enterprise systems
(SAP, older Oracle EBS, banking systems). ServiceNow supports both inbound SOAP (expose SN data via SOAP) and
outbound SOAP (call external SOAP services).

// ■■ OUTBOUND SOAP call to a legacy HR system ■■■■■■■■■■■■■■■■■■■■■

// Navigate: System Web Services > Outbound > SOAP Messages > New

// Name: 'Legacy HR SOAP Service'

// WSDL URL: [Link]

// Click 'Get WSDL' — ServiceNow auto-generates methods from the WSDL

// Business Rule script using the SOAP Message:

var soapMsg = new sn_ws.SOAPMessageV2('Legacy HR SOAP Service', 'getEmployee');

[Link]('employeeId', current.u_employee_id);

[Link](15000); // 15 second timeout

try {

var response = [Link]();

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 12

var body = [Link]();

// SOAP responses are XML — use GlideXMLUtil to parse

var xmlDoc = new XMLDocument2();

[Link](body);

var salary = [Link]('//getEmployeeResponse/salary');

var dept = [Link]('//getEmployeeResponse/department');

current.u_salary_band = salary;

[Link](dept);

[Link]();

} catch(e) {

[Link]('HR SOAP call failed: ' + [Link]());

// ■■ INBOUND SOAP — expose a ServiceNow Web Service ■■■■■■■■■■■■■■■

// Navigate: System Web Services > Create a Scripted Web Service

// This exposes a SOAP endpoint other systems can call

// Generally AVOID for new integrations — use REST instead

// Only needed for: legacy SOAP clients that can't do REST

// or strict WS-Security environments

10. Import Set REST API — bulk inbound data push


// External system pushes employee data directly to SN Import Set staging

// No file needed — pure REST push

// Single record push:

POST /api/now/import/u_hr_employee_import

Auth: Basic sn_import_user:password

Body:

"u_employee_id": "EMP12345",

"u_first_name": "Sarah",

"u_last_name": "Connor",

"u_email": "[Link]@[Link]",

"u_department": "Engineering",

"u_status": "ACTIVE"

// ServiceNow immediately runs the associated Transform Map

// Response includes transform result:

"result": {

"status": "updated",

"sys_id": "user_sys_id_here",

"display_value": "[Link]"

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 13

// Batch push (multiple records in one call):

POST /api/now/import/u_hr_employee_import

Body: [

{ "u_employee_id": "EMP001", "u_first_name": "Alice", ... },

{ "u_employee_id": "EMP002", "u_first_name": "Bob", ... }

// Each record is transformed independently — one error doesn't block others

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 14

PART 4 — Interview Q&A (15 Questions)

What is the difference between the Table API, Scripted REST API, and Import Set
Q1 Mid
API in ServiceNow?

Table API: out-of-the-box, no config needed. Full CRUD on any table.

GET/POST/PATCH/DELETE /api/now/table/{table}. Best for simple integrations

where the external system can directly map to ServiceNow table fields.

Scripted REST API: custom endpoints YOU build. Full control over request

parsing, response structure, and business logic. Best when you need complex

validation, multiple table writes per call, or a cleaner API contract for

consumers. Import Set API: push raw data to a staging table, have Transform

Map handle all the mapping and coalescing. Best for bulk data loads where

field mapping logic is complex or maintained separately from the API contract.

Walk me through setting up OAuth 2.0 for an outbound REST integration with
Q2 Senior
Salesforce from ServiceNow.

1. In Salesforce: create a Connected App (Setup > App Manager > New),

enable OAuth settings, set callback URL to ServiceNow's oauth_redirect.do,

select required scopes (api, refresh_token), get Client ID and Secret.

2. In ServiceNow: System OAuth > Application Registry > New > 'Connect to

a third party OAuth provider'. Name: Salesforce | Client ID/Secret from

step 1 | Token URL: [Link] |

Auth URL: [Link]

3. Click 'Get OAuth Token' — ServiceNow browser redirects to Salesforce

login, you authorize, token is stored in ServiceNow's OAuth token table.

4. Create REST Message: Auth Type = OAuth 2.0, select the OAuth profile.

5. ServiceNow auto-handles token refresh — when access token expires (1h),

it uses the refresh token to get a new one transparently.

CODING: Write a Scripted REST API endpoint that accepts a JSON payload from
Q3 Coding
an external monitoring tool and creates a ServiceNow Incident.

// Scripted REST API Resource: POST /api/x_myco/monitoring/alert

(function process(request, response) {

// ■■ Input validation ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

var payload;

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 15

try {

payload = [Link]([Link]);

} catch(e) {

[Link](400);

[Link]({ error: 'Invalid JSON' });

return;

var required = ['summary', 'severity', 'source_system'];

for (var i = 0; i < [Link]; i++) {

if (!payload[required[i]]) {

[Link](422);

[Link]({ error: 'Missing field: ' + required[i] });

return;

// ■■ Map severity to ServiceNow priority ■■■■■■■■■■■■■■■■■■■■■■■■

var priorityMap = {

'critical': '1', 'high': '2', 'medium': '3', 'low': '4'

};

var priority = priorityMap[[Link]()] || '3';

// ■■ Find assignment group from source system ■■■■■■■■■■■■■■■■■■■

var groupName = [Link](

'[Link].' + payload.source_system, 'Service Desk');

// ■■ Deduplicate: check for existing open incident ■■■■■■■■■■■■■■

var existing = new GlideRecord('incident');

if (payload.alert_id) {

[Link]('u_external_alert_id', payload.alert_id);

[Link]('state', 'IN', '1,2,3');

[Link]();

if ([Link]()) {

[Link](200);

[Link]({

status: 'existing',

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 16

number: [Link]('number'),

sys_id: [Link]()

});

return;

// ■■ Create the Incident ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

var inc = new GlideRecord('incident');

[Link]();

inc.short_description = '[' + payload.source_system + '] ' + [Link];

[Link] = [Link] || '';

[Link] = priority;

[Link] = 'monitoring';

inc.u_external_alert_id = payload.alert_id || '';

inc.u_source_system = payload.source_system;

inc.assignment_group.setDisplayValue(groupName);

var sysId = [Link]();

[Link](201);

[Link]({

status: 'created',

number: [Link]('number'),

sys_id: sysId

});

})(request, response);

How do you secure a Scripted REST API endpoint that receives webhooks from
Q4 Senior
external systems?

Multiple layers: 1) Basic Auth or OAuth 2.0 on the endpoint — the external

system must authenticate. Create a dedicated service account with minimum

required role (only the role needed to write to the target table). Never

use admin credentials for integration service accounts. 2) HMAC signature

validation — many webhook providers (GitHub, Stripe, Jira) sign the request

body with a shared secret. In your Scripted REST script, recompute the

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 17

HMAC signature from the raw body and compare it to the X-Signature header.

If they don't match, return 401 immediately. 3) IP allowlisting — in

System Properties or via a custom validation, check [Link]()

against an allowlist of the external system's egress IPs. 4) Rate limiting

— track calls from the integration user in a custom table and return 429

if they exceed your defined threshold in a time window.

What is the difference between synchronous and asynchronous outbound REST


Q5 Senior
calls and when do you use each?

Synchronous ([Link]()): the script WAITS for the external API to respond

before continuing. The calling user's browser is blocked during this wait.

Use ONLY in: Async Business Rules (background thread, user already returned)

Scheduled Jobs, Script Includes called from background scripts. NEVER in

Before/After Business Rules triggered by user saves — if the API takes 5

seconds, the user waits 5 seconds for their save to complete.

Asynchronous ([Link]()): script fires the request and returns

immediately. The response is processed in a callback or ignored.

Use in: After Business Rules, non-blocking notification calls, fire-and-forget

integrations. The golden rule: if you're in a Business Rule triggered by a user

save, use either Async Business Rule type OR [Link]() to avoid

degrading the user experience with external API latency.

CODING: Write a complete OAuth 2.0 token refresh handler for a Scripted REST
Q6 Coding
API outbound call.

function callWithTokenRefresh(restMsgName, methodName, params) {

var rm = new sn_ws.RESTMessageV2(restMsgName, methodName);

// Apply params

for (var key in params) {

[Link](key, params[key]);

var response = [Link]();

// If 401, token expired — force refresh and retry once

if ([Link]() == 401) {

[Link]('Token expired — refreshing OAuth token for ' + restMsgName);

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference


ServiceNow REST & SOAP Integrations — Complete End-to-End Guide + Interview Q&A Page 18

// Clear cached token to force re-authentication

var tokenGr = new GlideRecord('oauth_credential');

[Link]('credential_store.name', restMsgName + ' OAuth');

[Link]();

if ([Link]()) {

tokenGr.access_token = '';

tokenGr.expire_time = '';

[Link]();

// Retry — new token fetched automatically

rm = new sn_ws.RESTMessageV2(restMsgName, methodName);

for (var k in params) [Link](k, params[k]);

response = [Link]();

return response;

How do you handle bidirectional sync between ServiceNow and Jira without
Q7 Senior
creating infinite loops?

The key is a 'source system' flag to prevent echoes. Pattern:

1. Add a field u_jira_key to the SN record and u_servicenow_id to the Jira issue.

2. Add a field u_syncing_from_jira (boolean) on the SN record.

3. Outbound (SN -> Jira): Business Rule fires on SN change.

Condition: current.u_syncing_from_jira == false (don't sync if update

came FROM Jira — prevents echo). Set Jira issue via REST call.

4. Inbound (Jira -> SN): Jira webhook calls your Scripted REST API.

Script sets u_syncing_from_jira = true before updating, then

calls update(), then sets it back to false after. The Business Rule

condition prevents the outbound call from firing during this update.

5. Alternatively: check if the changing fields are ONLY ones that Jira

updates — if so, skip the outbound call. More elegant but harder to maintain.

[Link] | [Link] | [Link] REST SOAP Integration Expert Reference

You might also like