ServiceNow Bi-Directional Sync
Bi-directional synchronization between Incidents and ServiceNow enables real-time incident updates across both systems. Changes made in either system automatically propagate to the other within seconds.
Overview
The bi-directional sync provides:
- Real-time Updates: Changes sync within 5 seconds
- Field Ownership: Control which system owns each field
- Conflict Resolution: Automatic handling of simultaneous edits
- Drift Detection: Periodic reconciliation to catch missed updates
Prerequisites
- ServiceNow instance with admin access
- API user with incident table permissions
- Network connectivity between systems
- Webhook endpoint accessible from ServiceNow
Configuration
Step 1: Create Integration
Use the CLI to create a new ServiceNow integration:
im integration configure \
--name "Production ServiceNow" \
--type servicenow \
--org acme-corp \
--base-url "https://your-instance.service-now.com" \
--direction bidirectional \
--username "api_user" \
--password "your_password"Or use the API:
curl -X POST http://localhost:8080/api/v1/integrations \
-H "Content-Type: application/json" \
-d '{
"organization_id": "acme-corp",
"integration_type": "servicenow",
"name": "Production ServiceNow",
"base_url": "https://your-instance.service-now.com",
"credentials": {
"username": "api_user",
"password": "your_password"
},
"sync_direction": "bidirectional",
"enabled": true
}'Step 2: Configure Webhook in ServiceNow
- Navigate to System Definition > Business Rules in ServiceNow
- Create a new Business Rule for the
incidenttable - Set trigger conditions: after insert, update
- Add the following script:
(function executeRule(current, previous) {
var payload = {
sys_id: current.sys_id.toString(),
number: current.number.toString(),
short_description: current.short_description.toString(),
state: current.state.toString(),
priority: current.priority.toString(),
impact: current.impact.toString(),
assigned_to: current.assigned_to.getDisplayValue(),
updated_on: current.sys_updated_on.toString()
};
var request = new sn_ws.RESTMessageV2();
request.setEndpoint("https://your-incidents-server/api/v1/webhooks/{integration_id}");
request.setHttpMethod("POST");
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("X-ServiceNow-Signature", generateSignature(JSON.stringify(payload)));
request.setRequestBody(JSON.stringify(payload));
request.execute();
})(current, previous);Step 3: Configure Field Ownership
Set up field ownership rules to control which system is authoritative for each field:
# Platform owns severity and title
im integration field-ownership set prod-snow severity --owner platform --priority 10
im integration field-ownership set prod-snow title --owner platform --priority 10
# ServiceNow owns assignment and work notes
im integration field-ownership set prod-snow assigned_to --owner external --priority 5
im integration field-ownership set prod-snow work_notes --owner external --priority 5Field Mapping
| Incidents Field | ServiceNow Field | Default Owner |
|---|---|---|
title |
short_description |
Platform |
description |
description |
Platform |
severity |
priority + impact |
Platform |
status |
state |
Platform |
assigned_to |
assigned_to |
External |
work_notes |
work_notes |
External |
Status Mapping
| Incidents Status | ServiceNow State |
|---|---|
open |
New (1), In Progress (2) |
mitigated |
On Hold (3), Pending (4) |
resolved |
Resolved (6) |
closed |
Closed (7) |
Conflict Resolution
When simultaneous edits occur within 5 seconds, the configured resolution strategy is applied:
Last-Write-Wins (Default)
The most recent update takes precedence:
im integration configure prod-snow --conflict-strategy last-write-winsOwnership-Priority
The system with higher ownership priority for the field wins:
im integration configure prod-snow --conflict-strategy ownership-priorityManual Review
Conflicts are queued for manual resolution:
im integration configure prod-snow --conflict-strategy manual-review
# View pending conflicts
im conflict list --integration prod-snow
# Resolve a conflict
im conflict resolve conflict-123 --use-platformDrift Detection
Run periodic reconciliation to detect and fix drift:
# Check for drift without making changes
im integration reconcile prod-snow --dry-run
# Auto-heal detected drift
im integration reconcile prod-snow --auto-heal
# View reconciliation history
im integration reconcile history prod-snowScheduled Reconciliation
Configure automatic drift detection via the API:
curl -X POST http://localhost:8080/api/v1/integrations/{id}/reconcile/schedule \
-H "Content-Type: application/json" \
-d '{
"interval": "1h",
"auto_heal": true,
"enabled": true
}'Monitoring
View Sync Status
# Check integration health
im integration sync-status prod-snow
# View linked incidents
im integration links prod-snow --format tableDead Letter Queue
Failed syncs are queued for retry:
# View failed entries
im integration dlq prod-snow
# Retry a failed entry
im integration dlq-retry prod-snow entry-123
# Discard permanently failed entry
im integration dlq-discard prod-snow entry-456Testing
Test the integration connection:
im integration test prod-snowTroubleshooting
Common Issues
Webhook not receiving events
- Verify ServiceNow can reach your webhook endpoint
- Check the business rule is active and correctly configured
- Validate HMAC signature is being generated correctly
Sync delays
- Check network latency between systems
- Verify rate limiting is not being triggered
- Review the outbox queue for backlog
Field not syncing
- Confirm field ownership rules are configured
- Check field mapping exists for the field
- Verify the field is included in webhook payload
Debug Logging
Enable detailed sync logging:
export INCIDENTS_LOG_LEVEL=debug
export INCIDENTS_SYNC_TRACE=true