ServiceNow Integration

    What you are going to learn:

  • How the ServiceNow integration works
  • How to configure your ServiceNow instance for Obkio
  • How to configure the integration in Obkio
  • How to troubleshoot the integration

Note: The ServiceNow integration is only available in the Premium Subscription Plan.

The ServiceNow integration sends Obkio notifications to your ServiceNow instance. When Obkio detects a Network Issue, an incident is opened in ServiceNow. When the issue recovers, the same incident is resolved. There is no need to create tickets manually or to copy the monitoring data from Obkio.

How It Works
How It Works

  • Obkio sends each event to an Import Set table in your ServiceNow instance using the ServiceNow Import Set API. A Transform Map then creates or updates the incident.
  • One Obkio issue = one ServiceNow incident. Each issue has a unique correlation ID. When the issue gets worse or better, the same incident is updated instead of creating a duplicate. If the issue comes back after it was closed in Obkio, a new incident is opened.
  • When the issue recovers, Obkio sends a resolve event and the incident is resolved. The resolve event keeps the highest severity reached during the issue.
  • The integration is configured for the whole organization and uses the same rules as the other notification types: only the issues that reach your organization's Minimum Notification Severity are sent to ServiceNow. Notification delays and muted notifications also apply.
  • Issues from Monitoring Sessions, Network Devices, Device Interfaces, APM Tests (including Microsoft Teams tests) and Obkio Vision are sent.
  • The integration is one-way: acknowledging or closing an incident in ServiceNow has no effect in Obkio.

Obkio severity levels are sent in the u_severity field: info, warning, error or critical.

Requirements
Requirements

  • ServiceNow: Washington D.C. release or later. The API Key authentication used by Obkio (the x-sn-apikey HTTP header) is not available in earlier releases. To check your release, go to System Diagnostics -> Stats and look at the Build name.
  • ServiceNow: An administrator who can create tables, transform maps and API access policies. The admin role is required to run the optional scripts below.
  • Obkio: The Premium Subscription Plan.
  • Obkio: The Administrator role in your Obkio organization.

Part 1: ServiceNow Configuration
Part 1: ServiceNow Configuration

Step 1: Create the Import Set Table
Step 1: Create the Import Set Table

The Import Set table is the staging table where Obkio sends the alert data.

  1. Go to System Definition -> Tables and click New.
  2. Set the Label to Obkio Alert. The Name is generated automatically (for example u_obkio_alert). Note this name: it is the Table Name you will enter in Obkio.
  3. In Extends table, select Import Set Row (sys_import_set_row).
  4. Leave Auto-number unchecked and click Submit.

Step 2: Add the Columns
Step 2: Add the Columns

Obkio sends flat fields (not nested JSON), all as strings. Add a String column for each field below. ServiceNow ignores the fields that don't have a column, so you can start with the core fields and add the optional fields later.

Core fields

Column NameMax LengthDescription
u_v10Event schema version (always 1)
u_sn_event_action20open, or resolve when the issue recovers
u_correlation_id100Unique identifier of the Obkio issue
u_correlation_display50Always Obkio
u_title255Issue title, for example High packet loss
u_summary500Issue details (agents or device, and the issue)
u_severity20info, warning, error or critical
u_service100Type of monitored object (see the optional fields)
u_service_key100Identifier of the monitored object
u_service_ci_sys_id32Reserved for CMDB linking (always empty)
u_source255Event source, for example obkio:device:123
u_observed_at50Event date and time (ISO 8601, UTC)

Optional fields, which give more context on the issue:

Column NameMax LengthDescription
Event
u_event_type50Issue type, for example latency
u_event_number20Event sequence number
Monitoring Sessionsu_service: network_monitoring_session
u_session_key100Identifier of the Monitoring Session
u_generator255Name of the generator agent
u_generator_id50ID of the generator agent
u_reflector255Name of the reflector agent
u_reflector_id50ID of the reflector agent
u_monitoring_name255Name of the Monitoring Template
u_monitoring_id50ID of the Monitoring Template
Network Devicesu_service: device
u_device_id50ID of the Network Device
u_device_name255Name of the Network Device
u_collector_agent255Name of the collector agent
Device Interfacesu_service: device_interface
u_interface_id100ID of the interface
u_interface_name255Name of the interface
u_interface_index20SNMP index of the interface
APM Testsu_service: apm, apm_test_teams (Microsoft Teams)
u_apm_id100ID of the APM Test
u_apm_name255Name of the APM Test
u_apm_type50Type of APM Test
u_apm_agent255Name of the agent running the test
u_apm_teams_id100ID of the Microsoft Teams test
Obkio Visionu_service: vision
u_destination_test_id50ID of the destination test
u_destination_test_name255Name of the destination test
u_agent_id50ID of the agent running the test
u_agent_name255Name of the agent running the test
Metrics (latency, jitter and packet loss issues only)
u_latency_ms20Latency in milliseconds
u_jitter_ms20Jitter in milliseconds
u_loss_pct20Packet loss in percent

To create all the columns at once, you can run this script in System Definition -> Scripts - Background (change tableName if your table has another name):

var tableName = 'u_obkio_alert';

var columns = [
    {name: 'u_v', length: 10},
    {name: 'u_sn_event_action', length: 20},
    {name: 'u_correlation_id', length: 100},
    {name: 'u_correlation_display', length: 50},
    {name: 'u_title', length: 255},
    {name: 'u_summary', length: 500},
    {name: 'u_severity', length: 20},
    {name: 'u_service', length: 100},
    {name: 'u_service_key', length: 100},
    {name: 'u_service_ci_sys_id', length: 32},
    {name: 'u_source', length: 255},
    {name: 'u_observed_at', length: 50},
    {name: 'u_event_type', length: 50},
    {name: 'u_event_number', length: 20},
    {name: 'u_session_key', length: 100},
    {name: 'u_generator', length: 255},
    {name: 'u_generator_id', length: 50},
    {name: 'u_reflector', length: 255},
    {name: 'u_reflector_id', length: 50},
    {name: 'u_monitoring_name', length: 255},
    {name: 'u_monitoring_id', length: 50},
    {name: 'u_device_id', length: 50},
    {name: 'u_device_name', length: 255},
    {name: 'u_collector_agent', length: 255},
    {name: 'u_interface_id', length: 100},
    {name: 'u_interface_name', length: 255},
    {name: 'u_interface_index', length: 20},
    {name: 'u_apm_id', length: 100},
    {name: 'u_apm_name', length: 255},
    {name: 'u_apm_type', length: 50},
    {name: 'u_apm_agent', length: 255},
    {name: 'u_apm_teams_id', length: 100},
    {name: 'u_destination_test_id', length: 50},
    {name: 'u_destination_test_name', length: 255},
    {name: 'u_agent_id', length: 50},
    {name: 'u_agent_name', length: 255},
    {name: 'u_latency_ms', length: 20},
    {name: 'u_jitter_ms', length: 20},
    {name: 'u_loss_pct', length: 20}
];

columns.forEach(function(col) {
    var gr = new GlideRecord('sys_dictionary');
    gr.addQuery('name', tableName);
    gr.addQuery('element', col.name);
    gr.query();
    if (!gr.hasNext()) {
        gr.initialize();
        gr.name = tableName;
        gr.element = col.name;
        gr.column_label = col.name.replace('u_', '').replace(/_/g, ' ');
        gr.internal_type = 'string';
        gr.max_length = col.length;
        gr.insert();
        gs.info('Created column: ' + col.name);
    } else {
        gs.info('Column already exists: ' + col.name);
    }
});

Step 3: Create the Transform Map
Step 3: Create the Transform Map

The Transform Map converts the Obkio records into incidents.

  1. Go to System Import Sets -> Administration -> Transform Maps and click New.
  2. Set the Name to Obkio Alert to Incident.
  3. Set the Source table to your Import Set table (for example u_obkio_alert) and the Target table to Incident (incident).
  4. Click Submit.

Note: The field mapping dropdowns only list the columns that contain data. If the source fields are missing, insert a sample record in the Import Set table first, for example with this script in Scripts - Background (change u_obkio_alert if your table has another name), then refresh the Transform Map:

var gr = new GlideRecord('u_obkio_alert');
gr.initialize();
gr.u_v = '1';
gr.u_sn_event_action = 'open';
gr.u_correlation_id = 'setup:test:001';
gr.u_correlation_display = 'Obkio';
gr.u_title = 'Test alert for field mapping setup';
gr.u_summary = 'This record enables field mapping in Transform Map';
gr.u_severity = 'info';
gr.u_service = 'network_monitoring_session';
gr.u_service_key = 'test-123';
gr.u_source = 'obkio:setup:test';
gr.u_observed_at = '2025-01-01T00:00:00.123Z';
gs.info('Created sample record: ' + gr.insert());

You can delete this record (u_correlation_id = setup:test:001) once the field maps are created.

Step 4: Add the Field Maps
Step 4: Add the Field Maps

In the Transform Map, add these field maps (manually or with Mapping Assist):

Source FieldTarget FieldField Map Settings
u_correlation_idcorrelation_idCoalesce checked
u_correlation_displaycorrelation_display
u_titleshort_description
u_summarydescription
u_observed_atopened_atDate format
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
  • Coalesce must be checked on u_correlation_id. This is what updates the same incident for the whole issue instead of creating a new incident for each event.
  • The Date format matches the date sent by Obkio, in UTC with the ISO 8601 format and always three digits after the second (for example 2026-08-18T14:20:23.457Z). Without this date format, opened_at stays empty. Use three S, not six: in ServiceNow a S is a millisecond, not a digit, so .SSSSSS reads the fraction as a number of milliseconds and sets opened_at several minutes after the event.

Step 5: Add the Transform Script
Step 5: Add the Transform Script

The transform script sets the incident urgency from the Obkio severity, resolves the incident when the issue recovers and adds the issue details in the work notes. In the Transform Map, open the Transform Scripts related list, click New, set When to onBefore and paste this script:

(function runTransformScript(source, map, log, target) {

    // Obkio severity -> ServiceNow urgency
    var severity = source.u_severity.toString().toLowerCase();
    if (severity === 'critical') {
        target.urgency = '1'; // High
    } else if (severity === 'error') {
        target.urgency = '2'; // Medium
    } else {
        target.urgency = '3'; // Low (warning, info)
    }

    // Incident state
    var snEventAction = source.u_sn_event_action.toString().toLowerCase();
    if (snEventAction === 'resolve') {
        target.state = '6'; // Resolved
        target.close_code = 'Solved (Permanently)';
        target.close_notes = 'Network issue resolved - monitored by Obkio';
    } else if (snEventAction === 'open') {
        // Only on creation, so an incident In Progress is not reset to New
        if (target.operation() == 'insert') {
            target.state = '1'; // New
        }
    }

    // Work notes
    var workNote = 'Obkio Network Monitoring Update\n';
    workNote += 'Service: ' + source.u_service + '\n';
    workNote += 'Event Type: ' + (source.u_event_type || 'N/A') + '\n';
    workNote += 'Severity: ' + source.u_severity + '\n';
    workNote += 'Observed At: ' + source.u_observed_at + '\n';
    if (source.u_generator) workNote += 'Generator: ' + source.u_generator + '\n';
    if (source.u_reflector) workNote += 'Reflector: ' + source.u_reflector + '\n';
    if (source.u_monitoring_name) workNote += 'Monitoring: ' + source.u_monitoring_name + '\n';
    if (source.u_device_name) workNote += 'Device: ' + source.u_device_name + '\n';
    if (source.u_interface_name) workNote += 'Interface: ' + source.u_interface_name + '\n';
    if (source.u_collector_agent) workNote += 'Collector: ' + source.u_collector_agent + '\n';
    if (source.u_apm_name) workNote += 'APM Test: ' + source.u_apm_name + '\n';
    if (source.u_apm_agent) workNote += 'Agent: ' + source.u_apm_agent + '\n';
    if (source.u_destination_test_name) workNote += 'Destination: ' + source.u_destination_test_name + '\n';
    if (source.u_agent_name) workNote += 'Agent: ' + source.u_agent_name + '\n';
    if (source.u_latency_ms) workNote += 'Latency: ' + source.u_latency_ms + ' ms\n';
    if (source.u_jitter_ms) workNote += 'Jitter: ' + source.u_jitter_ms + ' ms\n';
    if (source.u_loss_pct) workNote += 'Packet Loss: ' + source.u_loss_pct + '%\n';
    target.work_notes = workNote;

})(source, map, log, target);

Note: The close_code choices are different between ServiceNow releases. If Solved (Permanently) is not a valid choice on your instance, the incident is not resolved. Use a value from your incident form.

Step 6: Create the API Key
Step 6: Create the API Key

Obkio authenticates to ServiceNow with an API Key sent in the x-sn-apikey HTTP header.

  1. Inbound Authentication Profile: Go to System Web Services -> API Access Policies -> Inbound Authentication Profile and click New. Set the Name to Obkio API Key, the Authentication method to API Key, the API key location to HTTP Header and the HTTP header name to x-sn-apikey. Check Active and click Submit.
  2. REST API Key: Go to System Web Services -> API Access Policies -> REST API Keys and click New. Set the API key name to Obkio Integration and select the integration User. This user needs the import_set_loader role. Check Active and click Submit. Copy the generated key: it is the New API Key you will enter in Obkio.
  3. REST API Access Policy: Go to System Web Services -> API Access Policies -> REST API Access Policies and click New. Set the Name to Obkio Import Set Access and the REST API to Import Set API, and check Active. In the Authentication Profiles section, add the Obkio API Key profile, then click Submit.

Note: The API Key must be authorized on the Import Set API. Obkio sends the alerts to /api/now/import/<Table Name> on your instance.

Part 2: Obkio Configuration
Part 2: Obkio Configuration

  1. In the Obkio App, go to the Organization Advanced Parameters (Menu -> Organization Name -> Change Organization's Advanced Parameters). In the General tab, scroll down to the ServiceNow Key section.
  2. Check Enable ServiceNow integration.
  3. Fill in the three fields:
    • URL: The base URL of your ServiceNow instance only, for example https://your-instance.service-now.com. It must start with https://. Don't add /api/now/...: Obkio adds /api/now/import/<Table Name> itself.
    • Table Name: The Name of the Import Set table from Step 1 (for example u_obkio_alert), not its Label.
    • New API Key: The REST API Key from Step 6.
  4. The settings are saved automatically once all three fields are filled. Until then, the note All ServiceNow fields are required — changes are saved once the section is complete. is shown.
  5. Click Send Test To ServiceNow. The message A test has been sent to ServiceNow confirms that the test record was accepted by ServiceNow. In ServiceNow, a record with the title Test record from Obkio is added to the Import Set table. If the Transform Map is active, an incident is also created: you can close it.

Screencapture Obkio ServiceNow Integration Settings

Once saved, the API Key is not displayed again: the read-only API Key field only shows its last 4 characters. To replace the key, enter the new key in the New API Key field. If this field is empty, the current key is kept.

Disable the Integration
Disable the Integration

To disable the integration, uncheck Enable ServiceNow integration and confirm with Remove. The ServiceNow configuration and the stored API Key are deleted. To enable the integration again, you will need to enter the three fields again.

Troubleshooting
Troubleshooting

Authentication Failed (401)
Authentication Failed (401)

The test shows Authentication failed. Please check your API key., or ServiceNow answers User is not authenticated.

  • Check that the URL contains only the instance address (https://your-instance.service-now.com), without any /api/now/... path. With an extra path, the request doesn't reach the Import Set API and the API Key is refused.
  • Check that the REST API Access Policy is active, uses the Import Set API and includes the Obkio API Key authentication profile.
  • Check that the REST API Key is active. Compare the last 4 characters shown in the API Key field in Obkio with your key. If they don't match, enter the key again in New API Key.

Access Denied (403) or Table Not Found (404)
Access Denied (403) or Table Not Found (404)

  • Access denied. The API key may not have write permissions for this table.: Check that the integration user has the import_set_loader role.
  • Import Set table '<Table Name>' not found. Please verify the table name.: Check the Table Name in Obkio. It is the table Name (for example u_obkio_alert), not its Label, and it is case-sensitive.

The Incident Date (opened_at) Is Empty or Wrong
The Incident Date (opened_at) Is Empty or Wrong

Check the Date format of the u_observed_at -> opened_at field map in the Transform Map. It must be yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. An empty opened_at usually means no date format is set, and an opened_at a few minutes after the event usually means the date format uses six S instead of three. See Step 4.

A New Incident Is Created for Each Event
A New Incident Is Created for Each Event

Check that Coalesce is checked on the u_correlation_id -> correlation_id field map.

Incidents Are Not Resolved
Incidents Are Not Resolved

Check that the transform script from Step 5 is active and that the close_code value is valid on your instance.

Nothing Is Received in ServiceNow
Nothing Is Received in ServiceNow

  • Only the issues that reach your organization's Minimum Notification Severity are sent to ServiceNow. For example, with the default value Error, Warning issues are not sent.
  • Use Send Test To ServiceNow to validate the URL, the table and the API Key.
  • Learn more on Notifications Troubleshooting.



Learn more ...