What It Is
An Approval is a record in the sysapproval_approver table that creates a mandatory human checkpoint in automated processes. When an Approval Activity in Flow Designer executes, it generates this record and immediately pauses the flow execution until a designated user either approves or rejects the request. The approval mechanism solves the fundamental business problem of requiring human judgment and authorization in otherwise automated workflows, ensuring that critical business decisions don't happen without proper oversight. Unlike notifications or tasks that can be ignored, approvals create hard stops that prevent process continuation until resolved.
Architecturally, approvals live in the Flow Designer application within the Process Automation suite, but their execution spans multiple ServiceNow layers. The sysapproval_approver table sits in the global scope and integrates with the broader approval engine that also powers legacy workflow approvals, journal field approvals, and custom approval implementations. Each approval record maintains a foreign key relationship to the source record through the source_table and document_id fields, while the sys_flow_context field links it back to the specific flow execution waiting for resolution.
The approval data model extends beyond the core sysapproval_approver table to include related tables like sys_approval (the parent approval request) and sys_user_delegate for delegation scenarios. When Flow Designer creates an approval, it automatically populates approval metadata including the approver's user record, due date calculations based on SLA definitions, and approval rules that determine escalation behavior. The execution environment treats approval records as active process waypoints, continuously monitoring their state changes through business rules and triggering flow resumption when the state field moves to approved or rejected.
You cannot function without approvals in scenarios requiring regulatory compliance, financial controls, or security authorization workflows. Change management processes mandating CAB approval before implementation, procurement workflows requiring manager authorization above spending thresholds, and access request procedures needing security team sign-off all depend on the approval mechanism to maintain audit trails and enforce business controls. Emergency change procedures that bypass normal approval gates still create approval records in a post-implementation state to maintain compliance documentation. Without approvals, organizations lose the ability to implement segregation of duties, maintain SOX compliance for financial processes, or satisfy audit requirements that demand documented authorization chains.
Platform admins manage approval configuration within Flow Designer, including approver assignment logic, due date calculations, and escalation rules, while developers extend approval functionality through custom approval engines and integration patterns. The admin-developer boundary becomes critical when implementing complex approval matrices that require scripted approver determination or when building approval dashboards that aggregate data across multiple approval types. Platform owners govern approval policies at the enterprise level, establishing approval templates, delegation frameworks, and compliance reporting structures that individual admins implement within their domain-specific flows.
Vancouver introduced significant improvements to approval handling with enhanced delegation capabilities and better integration between Flow Designer approvals and legacy workflow approvals. The approval engine now supports dynamic approver groups with real-time membership evaluation, and approval notifications integrate more seamlessly with the Now Mobile app for mobile approval scenarios. Xanadu added approval analytics capabilities and improved approval performance for high-volume scenarios, but also tightened security around approval record manipulation to prevent privilege escalation attacks through approval bypassing.
Where to Find and Configure It
Navigate to Process Automation > Flow Designer to configure Approval Activities within flows, where you define approver assignment, approval criteria, and escalation behavior. Access System Definition > Tables and search for sysapproval_approver to examine the approval record structure and configure custom approval fields. Use Self-Service > My Approvals to test approval interfaces and user experience from the approver perspective.
View active approval records at System Applications > Studio when working within scoped applications that contain custom approval logic or approval-related customizations. Monitor approval execution and troubleshoot issues through Process Automation > Flow Designer > Executions where approval activities show their current state and execution history. Configure approval templates and reusable approval logic in Process Automation > Flow Designer > Subflows for consistent approval patterns across multiple flows.
Scoped applications handle approvals differently than global applications, with scoped approvals restricted to approving records within the same application scope unless cross-scope access has been explicitly granted through application access controls. Global applications can create approvals for any table and assign any user as an approver, while scoped applications inherit approval templates from their parent scope but cannot modify global approval configurations.
Always test approval delegation scenarios in sub-production environments. The delegation logic executes at approval creation time, not at approval resolution time, which can cause unexpected behavior in complex organizational hierarchies.
How It Works Step by Step
The approval mechanism operates through a sophisticated interaction between Flow Designer's execution engine and the ServiceNow approval framework. When a flow reaches an Approval Activity, the system evaluates approver assignment rules, creates the approval record, sends notifications, and immediately suspends flow execution by storing the execution context in the sys_flow_context table. The approval record remains active until user interaction changes its state, at which point business rules trigger flow resumption with the approval decision available as flow data. This pause-and-resume pattern ensures that flows can handle long-running approval processes without consuming system resources during wait periods.
The approval engine maintains strict audit trails by logging every state change, delegation action, and escalation event in related audit tables. When approvers use delegation functionality, the system creates delegation records that preserve the original approver assignment while enabling the delegate to act on behalf of the original approver. Escalation logic evaluates due dates against current time stamps and can automatically reassign approvals, change approval requirements, or trigger alternative approval paths based on business rules configured in the Approval Activity.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.
The Execution Order
- Flow execution reaches Approval Activity and evaluates approver assignment conditions or scripts
- System creates
sysapproval_approverrecord withstate=requestedand links it to source record and flow context - Approval business rules fire on insert, triggering notification events and setting due dates based on SLA calculations
- Flow execution suspends and stores execution state in
sys_flow_contexttable with statuswaiting - User receives approval notification and acts through My Approvals interface or email integration
- Approval record state changes to
approvedorrejectedtriggering business rules that resume flow execution - Flow resumes with approval decision available as flow variable data for subsequent flow activities
// Common pattern for dynamic approver assignment in Approval Activity
(function getApprover() {
var approverUser = '';
var gr = new GlideRecord('incident');
if (gr.get(current.document_id)) {
// Get approver based on assignment group manager
if (gr.assignment_group) {
var groupGR = new GlideRecord('sys_user_group');
if (groupGR.get(gr.assignment_group)) {
approverUser = groupGR.manager;
}
}
// Fallback to caller's manager if no group manager
if (!approverUser && gr.caller_id) {
approverUser = gr.caller_id.manager;
}
}
return approverUser;
})();Real-World Scenarios
Emergency Change Approval with Auto-Escalation
Emergency changes require CAB chair approval within 30 minutes, with automatic escalation to CAB manager if not approved within that timeframe. The approval must capture emergency justification and maintain audit compliance even under time pressure.
Configure the Approval Activity with Approver set to the CAB chair user, Due date calculated as 30 minutes from current time using gs.minutesAgo(-30), and enable Escalation with escalation user set to CAB manager. Set the approval journal prompt to capture emergency justification with Journal required enabled. Configure notification templates to clearly indicate emergency status and include change details in approval notifications.
Watch for timezone issues in due date calculations that can cause premature escalations, and ensure escalation notifications don't trigger recursively if the CAB manager is unavailable. Test delegation scenarios where the CAB chair has delegated approval authority, as delegation records may not inherit the same escalation rules.
Multi-Level Procurement Approval Based on Amount
Purchase requests require different approval levels: manager approval for amounts under $1,000, director approval for $1,000-$5,000, and VP approval for amounts over $5,000. Each approval level must validate budget availability and maintain spending audit trails.
// Approval Activity condition script for procurement approvals
(function getApproverByAmount() {
var approverUser = '';
var requestGR = new GlideRecord('sc_request');
if (requestGR.get(current.document_id)) {
var totalAmount = parseFloat(requestGR.price || 0);
var requesterGR = new GlideRecord('sys_user');
if (requesterGR.get(requestGR.requested_for)) {
if (totalAmount < 1000) {
approverUser = requesterGR.manager;
} else if (totalAmount < 5000) {
// Get director from requester's department
var deptGR = new GlideRecord('cmn_department');
if (deptGR.get(requesterGR.department)) {
approverUser = deptGR.dept_head;
}
} else {
// VP approval - get from company hierarchy
approverUser = getVPForDepartment(requesterGR.department);
}
}
}
return approverUser;
})();Configure separate approval activities for each threshold level with conditional routing based on request amount, ensuring that approval notifications include budget impact analysis and remaining department budget information. Set up approval record custom fields to capture budget codes and cost center approvals for financial reporting integration.
Multi-level approvals can create approval loops if organizational hierarchy data is incomplete. Always implement fallback approvers and validate manager relationships before deploying procurement approval workflows.
Conditional Security Access Approval with Risk Assessment
Access requests for privileged systems require different approval paths based on risk scores: low-risk requests need only manager approval, while high-risk requests require security team approval plus CISO sign-off. The system must evaluate risk factors including user history, requested access level, and target system classification.
Create a subflow that calculates risk scores based on user security clearance, previous access violations, and target system security classification stored in a custom u_risk_score field on the access request record. Configure conditional approval activities that route to different approver groups based on calculated risk: route low-risk (score 1-3) to manager approval, medium-risk (score 4-6) to security team approval, and high-risk (score 7-10) to security team plus CISO sequential approvals. Set approval prompts to display risk assessment details and require risk acknowledgment in approval comments.
Monitor for risk score manipulation attempts by implementing field security on risk calculation fields and ensuring risk assessment logic runs server-side only. Test scenarios where security team members are unavailable or have conflicting approval assignments, as security approvals often involve on-call rotation schedules that change frequently.
The Classic Mistake
Setting the approval's Due Date to a fixed datetime value instead of using a duration, causing all approvals to expire immediately or never expire.
// BAD: Setting due_date to a fixed datetime in flow
var approval = new GlideRecord('sysapproval_approver');
approval.initialize();
approval.approver = 'admin';
approval.document_id = current.sys_id;
approval.source_table = current.getTableName();
approval.state = 'requested';
// This sets ALL approvals to expire on the same date
approval.due_date = '2024-01-15 17:00:00';
// Or worse - using current datetime means instant expiration
approval.due_date = gs.nowDateTime();
approval.insert();
// User sees: "This approval expired before you could respond"
// System shows: state = 'expired' immediatelyThis fails because ServiceNow's approval engine runs a scheduled job every 15 minutes that automatically expires any approval where due_date is in the past, changing the state to expired. Users see approval requests that are already expired, or approvals that never expire because the fixed date is far in the future. The mistake is non-obvious because the approval record gets created successfully—the expiration happens silently in the background. Most admins don't realize the Expected start field on approval activities should define duration, not absolute dates.
// GOOD: Using duration-based due dates
var approval = new GlideRecord('sysapproval_approver');
approval.initialize();
approval.approver = 'admin';
approval.document_id = current.sys_id;
approval.source_table = current.getTableName();
approval.state = 'requested';
// Calculate due date as duration from now
var gdt = new GlideDateTime();
gdt.addDaysUTC(3); // 3 business days from creation
approval.due_date = gdt;
// Or use GlideDuration for more precision
var duration = new GlideDuration('3 00:00:00'); // 3 days
approval.due_date = gs.daysAgo(-3); // Alternative approach
approval.insert();Always set approval due dates as calculated durations from the current time, never as fixed datetime values. Use Flow Designer's duration picker or GlideDuration in scripts.
When to Use This vs Alternatives
Use Approvals when you need formal, auditable decision-making with clear approve/reject outcomes that can pause automation. This is the right tool when compliance requires documented approval trails, when decisions affect business risk, or when you need escalation and delegation capabilities built into the approval process.
When Approvals Are the Correct Choice
Choose Approvals over simple notifications when the process must stop and wait for a human decision before proceeding. Approvals provide built-in state management, delegation features, and escalation timers that notifications cannot match. Use them when you need to track who approved what and when, especially for Change Management, Purchase Requests, or any workflow where regulatory compliance demands audit trails.
When to Use Notifications Instead
Use Notifications with custom UI Actions when you need simple yes/no responses that don't require formal approval tracking. This approach works better for lightweight decisions like "acknowledge this alert" or "confirm this information is correct" where you don't need delegation, escalation, or detailed approval history. Notifications also perform better at scale since they don't create additional database records for tracking approval states.
When You Need Both Together
Combine Approvals with custom Notifications when you need pre-approval alerts or post-decision communications beyond ServiceNow's standard approval emails. Use Approvals for the formal decision process, then trigger custom notifications to inform stakeholders about approval outcomes or to send reminders with custom formatting. This hybrid approach works well for complex workflows where different audiences need different levels of detail about the approval process.
Platform Interactions & Side Effects
- Creates audit records in
sys_auditfor every state change (requested → approved/rejected), making approval history immutable even if the approval record is deleted - Triggers Business Rules on
sysapproval_approverinsert/update, which can cause unexpected notifications or workflow triggers if you have custom rules on this table - Respects ACLs on the
source_table—if the approver can't read the source record, the approval email shows limited information and approval may fail silently - Updates the
sys_updated_byandsys_updated_onfields on the source record when approval completes, which can break Change Management timelines or SLA calculations - Creates Journal entries in
sys_journal_fieldwhen approvers add comments, which appear in the Activity stream and count toward database storage limits - Interacts with User Preferences for email timing—users with
Email clientset toNonewon't receive approval notifications even if the notification is active - Scheduled Job
Approval Expirationruns every 15 minutes to expire overdue approvals, potentially causing memory issues if thousands of approvals expire simultaneously - Delegation records in
sys_user_delegateautomatically redirect approvals to delegates, but this happens at email generation time, not when the approval record is created - Flow Context gets suspended at the Approval Activity step, consuming memory until the approval completes—orphaned approvals can cause Flow Designer memory leaks over time
- Update Sets capture approval configuration but not approval data—migrating flows with pending approvals to other instances leaves approvals orphaned and flows stuck
Debugging and Troubleshooting
The most common failure symptoms include flows stuck at approval activities with no visible progress, approval emails that never arrive, or approvals that immediately show as expired. Admins typically see flows in Waiting status indefinitely, while users report never receiving approval notifications. Users who do receive emails often encounter "Invalid approval" errors when clicking approve/reject buttons, usually indicating the approval record was deleted or corrupted. Check System Log > Emails for notification failures and System Log > System for approval processing errors.
Look for specific error messages like "GlideFlowEngine: Approval activity failed to create approval record" in System Log > All, which indicates ACL restrictions or missing required fields. The error "Invalid MAC key for approval" appears when approval email links are corrupted or tampered with—this happens when the glide.servlet.approval.use_mac system property is enabled but MAC keys don't match. Use the Script Debugger on approval Business Rules to trace execution flow when approvals fail to update source records properly. Enable debug logging for the com.glide.approval logger to see detailed approval processing steps.
Performance issues manifest as slow approval creation or delayed email notifications, usually caused by complex Business Rules on sysapproval_approver or source tables. Monitor Stats > Slow Queries for database bottlenecks during approval creation. The Flow Designer execution details show approval activity duration—anything over 10 seconds indicates underlying issues. Check System Definition > Scheduled Jobs to ensure the Approval Expiration job isn't failing or taking too long to process expired approvals.
Diagnostic Checklist:
- Verify the approval record exists in
sysapproval_approverwith correctdocument_idandsource_tablevalues - Check if the approver user account is active and has a valid email address in their user profile
- Confirm the approver has read access to the source record by testing with their user account
- Review notification conditions and ensure approval notifications are active and not filtered by Business Rules
- Test email delivery by manually sending a test notification to the approver's email address
- Validate that
due_dateis in the future andstateisrequested, notexpired - Check Flow Context execution details for error messages or timeout issues at the approval activity step
Quick Reference
- Maximum 1000 approval records can be processed by the expiration job in a single run—larger batches get queued for the next cycle
- Approval email MAC keys expire after 30 days by default, controlled by
glide.servlet.approval.mac.expires_in_dayssystem property - Approval delegation only works for users, not groups—group approvals cannot be delegated automatically
- The
wf_executingfield on source records remains true until all approvals complete, not just when the first approval is created - Approval Activities in subflows inherit the parent flow's context but create separate approval records with independent expiration timers
- System property
glide.approval.allow_duplicate_sys_idsmust be true to create multiple approval records for the same document_id - Approvals created via Flow Designer automatically populate
wf_activityfield, but script-created approvals require manual population for proper flow linking - Approval emails use the source record's display value in the subject line, which can expose sensitive data in email logs
- Database view
sysapproval_approver_listautomatically joins approval records with source table data but may cause performance issues on large datasets - Inactive users can still complete approvals if they receive the email before deactivation, but new approvals cannot be assigned to inactive accounts