reporting-dashboards
Build ServiceNow reports (list/bar/pie/line/pivot/single-score) on sys_report, sys_dashboard layouts with widget placement, scheduled report delivery, and drill-down configuration.
sla-management
Configure ServiceNow SLAs — contract_sla definitions with start/stop/pause/cancel conditions, task_sla status checks, breach escalation, business-hours schedules, and compliance-rate aggregation.
Full skill instructions
SLA (Service Level Agreement) Management tracks and ensures service commitments are met.
| Component | Table | Purpose |
|---|---|---|
| SLA Definition | contract_sla | SLA rules and conditions |
| Task SLA | task_sla | SLA instance on a task |
| SLA Workflow | wf_workflow | SLA breach notifications |
| SLA Schedule | cmn_schedule | Business hours definition |
Task Created
↓
SLA Definition Conditions Match
↓
Task SLA Record Created
↓
Timer Starts (based on schedule)
↓
SLA Stages: In Progress → Breached (if not met)
↓
Task Resolved/Closed
↓
SLA Achieved or Breached
// Create SLA Definition (ES5 ONLY!)
var sla = new GlideRecord("contract_sla")
sla.initialize()
// Basic info
sla.setValue("name", "P1 Incident Response Time")
sla.setValue("type", "SLA") // SLA, OLA, UC
sla.setValue("table", "incident")
// Target duration
sla.setValue("duration_type", "response") // response or resolution
sla.setValue("duration", "PT15M") // 15 minutes (ISO 8601)
// Conditions - when SLA attaches
sla.setValue("start_condition", "priority=1^active=true")
sla.setValue("stop_condition", "work_notes.changesTo()")
sla.setValue("pause_condition", "state=3") // Pause when On Hold
sla.setValue("cancel_condition", "state=8") // Cancel when Cancelled
// Schedule (business hours)
sla.setValue("schedule", getScheduleSysId("8-5 M-F"))
// Enable
sla.setValue("active", true)
sla.insert()
// Start Condition: When SLA timer begins
// Example: P1 incidents when created
var startCondition = "priority=1^active=true^sys_created_onRELATIVEGT@minute@ago@0"
// Stop Condition: When SLA is achieved
// Example: When work notes are added (response) or resolved (resolution)
var responseStop = "work_notes.changes()"
var resolutionStop = "state=6^ORstate=7" // Resolved or Closed
// Pause Condition: Timer pauses
// Example: On Hold or Awaiting User Info
var pauseCondition = "state=3^ORstate=-5"
// Cancel Condition: SLA cancelled without breach
// Example: Incident cancelled or duplicate
var cancelCondition = "state=8^ORclose_code=Duplicate"
// Find SLAs for an incident (ES5 ONLY!)
var incidentSysId = "incident_sys_id"
var taskSla = new GlideRecord("task_sla")
taskSla.addQuery("task", incidentSysId)
taskSla.query()
while (taskSla.next()) {
gs.info(
"SLA: " +
taskSla.sla.getDisplayValue() +
" | Stage: " +
taskSla.stage.getDisplayValue() +
" | Breached: " +
taskSla.getValue("has_breached") +
" | Planned End: " +
taskSla.getValue("planned_end_time"),
)
}
// SLA Status Helper (ES5 ONLY!)
var SLAHelper = Class.create()
SLAHelper.prototype = {
initialize: function () {},
/**
* Get SLA status for a task
* @param {string} taskSysId - Task sys_id
* @returns {Array} - Array of SLA status objects
*/
getSLAStatus: function (taskSysId) {
var slaStatuses = []
var taskSla = new GlideRecord("task_sla")
taskSla.addQuery("task", taskSysId)
taskSla.addQuery("active", true)
taskSla.query()
while (taskSla.next()) {
var now = new GlideDateTime()
var plannedEnd = new GlideDateTime(taskSla.getValue("planned_end_time"))
var timeLeft = GlideDateTime.subtract(now, plannedEnd)
slaStatuses.push({
name: taskSla.sla.getDisplayValue(),
stage: taskSla.stage.getDisplayValue(),
hasBreached: taskSla.getValue("has_breached") === "true",
percentageComplete: taskSla.getValue("percentage"),
plannedEnd: taskSla.getValue("planned_end_time"),
timeLeft: this._formatDuration(timeLeft),
isAtRisk: this._isAtRisk(taskSla),
})
}
return slaStatuses
},
/**
* Check if any SLA is at risk (>75% elapsed)
*/
_isAtRisk: function (taskSla) {
var percentage = parseFloat(taskSla.getValue("percentage"))
return percentage >= 75 && taskSla.getValue("has_breached") !== "true"
},
_formatDuration: function (duration) {
var totalSeconds = duration.getNumericValue() / 1000
var hours = Math.floor(totalSeconds / 3600)
var minutes = Math.floor((totalSeconds % 3600) / 60)
return hours + "h " + minutes + "m"
},
type: "SLAHelper",
}
// Pause SLAs when incident goes On Hold (ES5 ONLY!)
// Business Rule: after, update, incident
;(function executeRule(current, previous) {
// Check if state changed to On Hold
if (current.state.changesTo("3")) {
pauseIncidentSLAs(current.getUniqueValue())
}
// Check if state changed from On Hold
if (previous.state == "3" && current.state != "3") {
resumeIncidentSLAs(current.getUniqueValue())
}
})(current, previous)
function pauseIncidentSLAs(incidentId) {
var taskSla = new GlideRecord("task_sla")
taskSla.addQuery("task", incidentId)
taskSla.addQuery("active", true)
taskSla.addQuery("stage", "!=", "breached")
taskSla.query()
while (taskSla.next()) {
var slaDef = new GlideRecord("contract_sla")
if (slaDef.get(taskSla.getValue("sla"))) {
// Only pause if SLA has pause condition
if (slaDef.getValue("pause_condition")) {
taskSla.pause = true
taskSla.pause_time = new GlideDateTime()
taskSla.update()
}
}
}
}
// SLA Workflow Activity: Send breach notification (ES5 ONLY!)
;(function executeActivity() {
var taskSla = current
var task = taskSla.task.getRefRecord()
// Get escalation recipients
var recipients = []
// Add assigned user
if (task.assigned_to) {
recipients.push(task.assigned_to.getValue("email"))
}
// Add assignment group manager
if (task.assignment_group) {
var group = task.assignment_group.getRefRecord()
if (group.manager) {
recipients.push(group.manager.email)
}
}
// Send notification
if (recipients.length > 0) {
gs.eventQueue("sla.breach.notification", task, recipients.join(","), taskSla.sla.getDisplayValue())
}
})()
// SLA Escalation Script Include (ES5 ONLY!)
var SLAEscalation = Class.create()
SLAEscalation.prototype = {
initialize: function () {},
/**
* Escalate breached SLA
*/
escalateBreached: function (taskSlaSysId) {
var taskSla = new GlideRecord("task_sla")
if (!taskSla.get(taskSlaSysId)) {
return false
}
var task = taskSla.task.getRefRecord()
// Increase priority
var currentPriority = parseInt(task.getValue("priority"), 10)
if (currentPriority > 1) {
task.setValue("priority", currentPriority - 1)
}
// Set escalation flag
task.setValue("escalation", 1)
// Add work note
task.work_notes = "SLA Breached: " + taskSla.sla.getDisplayValue() + "\nAutomatic escalation applied."
task.update()
// Notify on-call
this._notifyOnCall(task)
return true
},
_notifyOnCall: function (task) {
// Get on-call schedule
var oncall = new OnCallRotation()
var onCallUser = oncall.getOnCallUser(task.assignment_group)
if (onCallUser) {
gs.eventQueue("sla.oncall.notification", task, onCallUser.sys_id, "")
}
},
type: "SLAEscalation",
}
// Calculate SLA compliance rate (ES5 ONLY!)
function getSLAComplianceRate(slaName, startDate, endDate) {
var ga = new GlideAggregate("task_sla")
ga.addQuery("sla.name", slaName)
ga.addQuery("end_time", ">=", startDate)
ga.addQuery("end_time", "<=", endDate)
ga.addQuery("active", false) // Completed SLAs only
ga.addAggregate("COUNT")
ga.addAggregate("COUNT", "has_breached")
ga.groupBy("has_breached")
ga.query()
var total = 0
var breached = 0
while (ga.next()) {
var count = parseInt(ga.getAggregate("COUNT"), 10)
total += count
if (ga.getValue("has_breached") === "true") {
breached = count
}
}
if (total === 0) {
return { compliance: 100, total: 0, breached: 0 }
}
var achieved = total - breached
var compliance = Math.round((achieved / total) * 100 * 10) / 10
return {
compliance: compliance,
total: total,
achieved: achieved,
breached: breached,
}
}
// Usage
var stats = getSLAComplianceRate("P1 Incident Response", gs.beginningOfThisMonth(), gs.endOfThisMonth())
gs.info("P1 Response SLA Compliance: " + stats.compliance + "%")
| Tool | Purpose |
|---|---|
snow_find_artifact | Find SLA definitions |
snow_query_table | Query task_sla records |
snow_execute_script_with_output | Test SLA scripts |
snow_create_business_rule | Create SLA triggers |
// 1. Find existing SLAs
await snow_find_artifact({
type: "contract_sla",
name: "P1",
})
// 2. Query SLA breaches
await snow_query_table({
table: "task_sla",
query: "has_breached=true^end_time>=javascript:gs.beginningOfThisMonth()",
fields: "sla,task,end_time,business_duration",
})
// 3. Check SLA compliance
await snow_execute_script_with_output({
script:
'var stats = getSLAComplianceRate("P1 Response", gs.beginningOfThisMonth(), gs.endOfThisMonth()); gs.info(JSON.stringify(stats));',
})
Build ServiceNow reports (list/bar/pie/line/pivot/single-score) on sys_report, sys_dashboard layouts with widget placement, scheduled report delivery, and drill-down configuration.
Make outbound REST calls from ServiceNow with sn_ws.RESTMessageV2 — basic/bearer/OAuth/API-key auth, error handling by status code, response parsing, sys_rest_message records, and retry with exponential backoff.
Use tool_search to discover and enable lazy-loaded Serac MCP tools (snow_*, jira_*, github_*, etc). Explains naming conventions, search strategies, and always-available activity tools.
Build ServiceNow Automated Test Framework tests and suites — impersonation, form steps, assertions, server-side script steps, test parameters, and execution via snow_create_atf_test / snow_execute_atf_test.
Move data in and out of ServiceNow — CSV parsing into import sets, GlideImportSetTransformer runs, CSV/JSON/XML exports, scheduled data sources, bulk update and deleteMultiple safety patterns.
Configure ServiceNow Discovery — schedules, IP ranges, credential affinities, MID Server assignment, custom probes/sensors, identification rules, and run-status monitoring on discovery_* tables.
Build ServiceNow Customer Service Management — customer_account, customer_contact, sn_customerservice_case routing, service entitlements with usage decrement, and Customer Portal case submission widgets.
Manage ServiceNow dictionary (sys_dictionary), table/field creation, choice lists, dictionary overrides, and sys_data_policy2 rules that enforce mandatory/read-only/visible field behavior on the data layer.
Configure ServiceNow Mobile (Now Mobile/Agent) — sys_sg_mobile_app screens, card builders, push notifications, offline sync rules, mobile actions for barcode/GPS, and offline-queue change processing.
Create ServiceNow sysevent_email_action notifications — templates with substitution variables, mail scripts for dynamic content/recipients/attachments, custom events, weights, and digest configuration.
Enforce ES5-only syntax for ServiceNow server-side scripts (Rhino engine) — convert const/let, arrow functions, template literals, destructuring, for-of, and async/await to ES5 equivalents.
Create and transition ServiceNow change requests (normal/standard/emergency), change tasks, affected CIs, approval routing, CAB scheduling, and conflict detection across maintenance windows.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience