ServiceNow
Sync ServiceNow incidents to status dashboards via inbound webhooks.
ServiceNow can push incident creates and updates to StatusDashboard through a Business Rule on the Incident table. When an incident is inserted or updated in ServiceNow, your rule builds a signed JSON payload and POSTs it to the inbound webhook endpoint. StatusDashboard opens or advances the matching incident on your status dashboards and sends subscriber notifications when configured.
Configure a Business Rule on the Incident table in ServiceNow (and any supporting Script Includes) using the patterns below. All mapping lives in ServiceNow: which CMDB services map to which StatusDashboard components, how ServiceNow State maps to workflow phases, and how Impact maps to severity labels.
For payload fields, signing, and webhook logs, see Inbound webhooks. For component and workflow configuration, see Components and Workflows.
How it works
The integration is a one-way push from ServiceNow to StatusDashboard:
- A ServiceNow Business Rule runs after insert or after update on Incident [
incident]. - Your script reads the incident record (state, impact, descriptions, affected services).
- Your script maps ServiceNow values to StatusDashboard component IDs, severity labels, and workflow phase labels using dictionaries you maintain in the script.
- Your script signs the JSON body with your inbound webhook signing secret and POSTs to
https://api.statusdashboard.com/public/webhooks/inbound. - StatusDashboard validates the signature, queues the payload, and creates or updates an incident event.
sequenceDiagram
participant SN as ServiceNow Incident
participant BR as Business Rule
participant SD as StatusDashboard Inbound Webhook
participant SP as Status Dashboard
SN->>BR: Insert or update
BR->>BR: Map CMDB services to componentIds
BR->>BR: Map State and Impact
BR->>SD: Signed POST (trigger or update)
SD->>SP: Create or advance incidentBefore you begin
Confirm the following on both sides before writing the Business Rule.
StatusDashboard
| Requirement | Where to configure |
|---|---|
| Inbound webhook signing key | Inbound webhooks — create a key; copy the Key ID and Signing Secret (secret is shown once) |
| Components for each affected service | Components — note each component UUID (via List components if needed) |
| Severity labels that match your mapping | Severities — default labels include Degraded Performance, Partial Outage, and Major Outage |
| Incident workflow phase labels | Workflows — default phases include Investigating, Identified, Monitoring, and Resolved |
| Dashboards and component assignments | Dashboards — components referenced in webhooks must exist and be valid for the event |
ServiceNow
| Requirement | Notes |
|---|---|
| Incident table access | Business Rule on Incident [incident] |
| Outbound HTTPS | RESTMessageV2 (or equivalent) to api.statusdashboard.com on port 443 |
| Credential storage | Store Key ID and Signing Secret in a System Property, Credential, or encrypted script variable — not hard-coded in production |
| Custom incident field (recommended) | String field (for example u_statusdashboard_event_id) to store the StatusDashboard event UUID after the first successful trigger |
| CMDB service identifiers | sys_id values for Business Service, Configuration Item, and rows in Impacted Services/CIs (task_cmdb_ci_service) |
Step 1 — Create an inbound webhook signing key
- Open Inbound webhooks in the admin console.
- Click Create key and copy the Key ID (for example
wk_a1b2c3d4e5f6a7b8) and Signing Secret. - Store both values in ServiceNow where your integration script can read them.
The signing secret cannot be retrieved after the creation dialog closes. If it is lost, revoke the old key and create a new one.
See Authentication for the HMAC-SHA256 header format (X-SD-Key-Id, X-SD-Signature).
Step 2 — Collect StatusDashboard component IDs
Each incident webhook must include at least one StatusDashboard component UUID in componentIds.
- List your organization's components with
GET /app/components(see List components), or export IDs during initial setup. - Record the UUID next to each ServiceNow service you intend to map.
Example mapping table (maintain this in your ServiceNow script or a related list):
| ServiceNow source | ServiceNow sys_id | StatusDashboard component | Component UUID |
|---|---|---|---|
| Business service on incident | abc123… | API | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| Impacted CI (CMDB) | def456… | Payment Processing | b2c3d4e5-f6a7-8901-bcde-f12345678901 |
Finding ServiceNow service sys_id values
| ServiceNow object | How to locate the sys_id |
|---|---|
| Business service on the incident | Field Business service on the incident form |
| Configuration items | Filter navigator: cmdb_ci.list — open the CI, use Copy sys_id from the form header menu |
| Impacted Services/CIs | Related list Impacted Services/CIs on the incident — each row links to a CMDB service CI |
Your script should collect all relevant sys_id values (primary business service plus impacted services), deduplicate them, map each to a StatusDashboard component UUID, and send the resulting UUID array as componentIds (1–20 IDs per request).
If no mapped component is found, skip the webhook or log an error. StatusDashboard rejects triggers with unknown component IDs.
Step 3 — Define mapping dictionaries in ServiceNow
Add JavaScript objects at the top of your Business Rule (or in a Script Include) for the mappings below. Keys must match display values ServiceNow returns from getDisplayValue() unless you standardize on internal values.
State → workflow phase (statusLabel)
Map ServiceNow State to the exact incident workflow phase label configured in StatusDashboard (case-sensitive).
Default StatusDashboard incident phases:
| ServiceNow State (example) | StatusDashboard statusLabel |
|---|---|
| New | Investigating |
| In Progress | Identified |
| On Hold | Identified |
| Resolved | Resolved |
| Closed | Resolved |
| Cancelled | Resolved |
Customize the dictionary to match your ServiceNow state list and your organization's workflow labels on Workflows.
Impact → severity (severity)
Map ServiceNow Impact display values to StatusDashboard severity labels (also case-sensitive).
Default StatusDashboard severities:
| ServiceNow Impact (example) | StatusDashboard severity |
|---|---|
| 1 - High | Major Outage |
| 2 - Medium | Partial Outage |
| 3 - Low | Degraded Performance |
If you renamed severities in Settings, update the dictionary to match. You may omit severity on updates; severity is required on trigger only.
Description assembly
Decide how to build the StatusDashboard description from ServiceNow fields:
| Option | Behavior |
|---|---|
| Short description only | Use Short description |
| Short + long | Concatenate Short description and Description when the long field is populated |
Use Short description for the webhook title on trigger (max 250 characters).
Step 4 — Track the StatusDashboard event ID
Your Business Rule tracks which StatusDashboard event corresponds to each ServiceNow incident. Store the StatusDashboard event UUID on the incident record and reference it on every update.
Recommended pattern:
- Add a custom string field on Incident (for example
u_statusdashboard_event_id) to store the StatusDashboard event UUID. - On insert, send
action: "trigger"withidempotencyKeyset to the incidentsys_id(letters, numbers, dots, underscores, and hyphens only; max 128 characters). - After the first successful trigger, obtain the assigned event ID and write it to your custom field. Practical options:
- Webhook logs API: Call
GET /app/integrations/webhooks/inbound/logs(see List inbound webhook logs) and match the newestprocessedentry whose payload contains youridempotencyKey. Use the returnedeventId. - Manual (pilot): Copy the Event ID from the matching row on Inbound webhooks webhook logs during testing.
- Webhook logs API: Call
- On update, read
u_statusdashboard_event_id. If populated, sendaction: "update". If empty, treat the next operation as a trigger (with the sameidempotencyKey) or resolve the ID from logs before updating.
idempotencyKey prevents duplicate incidents when ServiceNow retries the same trigger. It is remembered for 3 days. It does not replace storing eventId for update actions — updates require the UUID explicitly.Optionally set a private webhook attribute on trigger so support staff can correlate records:
"attributes": [
{ "key": "servicenow_incident_id", "value": "<incident_sys_id>", "isPublic": false }
]Step 5 — Create the Business Rule
Create a Business Rule in ServiceNow with these settings:
| Setting | Value |
|---|---|
| Name | StatusDashboard Inbound Webhook (or your standard) |
| Table | Incident [incident] |
| Advanced | Checked |
| When | after |
| Insert | Checked |
| Update | Checked |
| Filter conditions (optional) | Limit to incidents that affect published services, specific assignment groups, or categories you expose on status dashboards |
Script structure (outline)
Implement the Advanced script using standard ServiceNow APIs. A typical flow:
- Load configuration — endpoint URL, Key ID, Signing Secret, mapping dictionaries, notification flags.
- Build
componentIds— query Business service, Impacted Services/CIs (task_cmdb_ci_service), map eachsys_idthrough your component dictionary; exit if the array is empty. - Choose
action:insert→triggerupdatewith storedeventId→updateupdatewithout storedeventId→triggerwithidempotencyKey(or resolve ID first)
- Build JSON payload — see Payload reference below.
- Sign the body — compute HMAC-SHA256 over
"<unix_seconds>.<raw_json_body>"with the Signing Secret; set headersContent-Type,X-SD-Key-Id, andX-SD-Signature: t=<seconds>,v1=<hex>. - Send —
RESTMessageV2POST tohttps://api.statusdashboard.com/public/webhooks/inbound. - Persist
eventId— on first successful processing, updateu_statusdashboard_event_id(via logs API poll or your chosen method). - Log — use
gs.info/gs.errorbehind a debug flag for troubleshooting.
Consider moving signing and HTTP into a Script Include (for example StatusDashboardWebhookClient) so the Business Rule stays readable and you can unit-test mappings separately.
Payload reference
All requests POST JSON to the inbound webhook endpoint. See Payload reference for full field definitions.
Trigger — new incident (action: "trigger")
Send on ServiceNow insert, or on update when no StatusDashboard eventId is stored yet.
{
"action": "trigger",
"title": "Elevated API error rate",
"description": "Customers may see timeouts on login. Engineering is engaged.",
"severity": "Major Outage",
"componentIds": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
"statusLabel": "Investigating",
"initialMessage": "Incident opened from ServiceNow.",
"idempotencyKey": "a1b2c3d4e5f6789012345678901234ab",
"notifications": true,
"attributes": [
{ "key": "servicenow_incident_id", "value": "a1b2c3d4e5f6789012345678901234ab", "isPublic": false }
]
}| Field | ServiceNow source (typical) |
|---|---|
title | Short description |
description | Short description and optionally Description |
severity | Impact via your severity dictionary |
componentIds | Mapped UUIDs from affected CMDB services |
statusLabel | State via your state dictionary |
idempotencyKey | Incident sys_id |
notifications | Set false when you need a silent create (see Notification suppression) |
Update — advance an existing incident (action: "update")
Send on ServiceNow update when u_statusdashboard_event_id is populated.
{
"action": "update",
"eventId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"statusLabel": "Identified",
"message": "Root cause identified. Fix rolling out to all regions.",
"notifications": true
}| Scenario | Suggested statusLabel | Suggested message |
|---|---|---|
| State changed (no customer comment) | Mapped new state | Short description change, or a fixed phrase such as "Incident updated in ServiceNow." |
| Customer visible comment posted | Current workflow phase (mapped from current State) | Text of the customer-visible comment (strip journal headers) |
| Resolved / Closed | Resolved (or your final phase label) | Resolution notes or Close notes when appropriate |
PATCH /app/events/{id} in the REST API or update the event in the admin console.Customer-visible comments
ServiceNow Customer visible comments map to StatusDashboard timeline entries.
When current.comments.changes() on an update:
- Read the latest customer-visible journal entry (
comments.getJournalEntry(1)). - Strip the journal header (text before the first newline) and trailing blank lines.
- Send
action: "update"withmessageset to the cleaned comment text andstatusLabelset to the phase mapped from the incident's current State.
If the user edits State, Impact, or descriptions and posts a customer-visible comment in one save, prefer one webhook that includes the comment as the timeline message and the updated statusLabel. Avoid posting the comment first and saving field changes separately, which can produce two StatusDashboard timeline entries and duplicate notifications.
Notification suppression
To suppress subscriber notifications for a specific webhook while still creating or updating the incident:
| Method | Behavior |
|---|---|
"notifications": false in the JSON payload | Disables notifications for that request (and can disable future notifications on update when set on an update action) |
| Magic string in Short description (custom pattern) | Remove a configured substring (for example {-}) from the description before sending, and set "notifications": false when the substring was present — useful for draft incidents in ServiceNow |
Inbound webhook notification defaults and segment targeting are documented on Inbound webhooks.
What triggers the Business Rule
Actions in ServiceNow that should send a webhook:
| ServiceNow action | StatusDashboard action |
|---|---|
| New incident inserted | trigger |
| State, Impact, or affected services change | update (when eventId is known) |
| Short description or Description change | No description sync via webhook — use timeline message to communicate, or PATCH via REST API |
| Customer-visible comment posted | update with comment as message |
Skip or filter incidents that should never appear on public status dashboards (internal-only categories, test assignment groups, and so on) using Business Rule conditions.
Testing and troubleshooting
- Enable debug logging in your script and watch System Logs in ServiceNow.
- Send a test incident with one mapped component and a known State / Impact.
- Open Inbound webhooks and review Webhook logs:
processed— incident created or updated; note the Event IDprocessing_failed— check Reason (invalid severity label, unknown component ID, invalid workflow phase, plan limits)validation_failed— malformed JSON or missing required fields
- Remember that authentication failures return
200 { "ok": true }by design. If nothing appears in logs, verify Key ID, Signing Secret, and the signature timestamp (must be within 5 minutes).
| Symptom | Likely cause |
|---|---|
Log shows processing_failed — invalid workflow phase | statusLabel does not exactly match a label on Workflows |
Log shows processing_failed — severity | severity does not match a label on Severities |
Log shows processing_failed — component | UUID wrong or component deleted |
| Duplicate incidents | Missing or inconsistent idempotencyKey on trigger |
| Updates ignored | eventId not stored on the ServiceNow incident |
| Two notifications for one edit | Comment posted and fields saved as separate ServiceNow transactions |

