What It Is
Web Services in ServiceNow are the platform's comprehensive API integration framework that enables bi-directional data exchange between ServiceNow instances and external systems. The platform supports four primary types: inbound REST APIs through Scripted REST APIs, outbound REST calls via REST Messages, inbound SOAP web services, and outbound SOAP calls through SOAP Messages. This architecture allows ServiceNow to both consume external APIs and expose its own data and functionality as consumable services. The web service framework handles authentication, data transformation, error handling, and logging automatically, while providing extensive customization options through server-side JavaScript scripting.
Architecturally, web services live in the System Web Services application and operate at the application server layer, intercepting HTTP requests before they reach the standard ServiceNow UI processing pipeline. Scripted REST APIs create custom endpoints under /api/[scope]/[api_name]/[resource], while REST Messages define outbound HTTP requests that execute from server-side scripts. The platform includes built-in web services for core functionality like the Table API (/api/now/table), Import Set API, and Attachment API, but most enterprise implementations require custom web services tailored to specific integration patterns.
The web service framework integrates directly with ServiceNow's security model through API authentication (Basic Auth, OAuth 2.0, mutual authentication), ACL evaluation, and field-level security. When processing requests, web services bypass the standard form processing but still respect table-level security, business rules, and data policies depending on configuration. The GlideRecord and GlideSystem server-side APIs are fully available within web service scripts, enabling complex data manipulation, workflow triggering, and business logic execution. Web services also integrate with ServiceNow's logging framework, writing detailed execution logs to sys_log and maintaining request/response history in sys_rest_message_log.
You cannot function without web services in any scenario requiring real-time data synchronization with external systems, automated provisioning workflows that span multiple platforms, or mobile applications that need lightweight API access to ServiceNow data. Critical use cases include HR onboarding that pushes employee data to Active Directory, incident management that creates tickets in vendor systems, asset management that pulls configuration data from discovery tools, and reporting that aggregates data from multiple sources. Without web services, these integrations require batch processing through scheduled imports, manual data entry, or complex middleware solutions that increase cost and maintenance overhead.
Platform owners typically define the overall web service architecture and authentication strategy, while developers implement the actual Scripted REST APIs and REST Message configurations with their business logic and error handling. Administrators manage web service security through role assignments, API access controls, and monitoring of web service usage and performance. In scoped applications, developers can create web services that are automatically namespaced and can be published to the application repository, but cross-scope access requires explicit configuration. The relationship between these roles becomes critical during troubleshooting, as web service issues often span security configuration (admin), business logic (developer), and infrastructure (platform owner) concerns.
Recent ServiceNow releases have significantly enhanced web service capabilities, particularly in Vancouver and Xanadu versions. Vancouver introduced improved OAuth 2.0 support with refresh token handling, enhanced REST Message response parsing for complex JSON structures, and better error handling with structured error responses. Xanadu added support for OpenAPI 3.0 specification generation for Scripted REST APIs, improved performance for high-volume API calls through connection pooling, and enhanced logging with correlation IDs for request tracing across distributed systems. The platform also introduced GraphQL support as a preview feature, allowing more flexible data querying patterns for complex integration scenarios.
Where to Find and Configure It
The primary configuration location is System Web Services > Scripted Web Services > Scripted REST APIs where you create and manage inbound API endpoints. For outbound web service calls, navigate to System Web Services > Outbound > REST Message to configure external API connections. SOAP-based integrations live under System Web Services > Inbound > SOAP for incoming SOAP requests and System Web Services > Outbound > SOAP Message for outbound SOAP calls.
In Studio or App Engine Studio, web services appear under the REST APIs and REST Messages sections where you can create scoped web services within your application. Web service security configuration lives in System Security > Access Control (ACL) where you can create rules for specific API endpoints. Authentication providers are managed under System OAuth > Application Registry for OAuth 2.0 integrations.
Active web service requests and responses are logged in the sys_rest_message_log table, accessible via System Logs > REST Messages. Web service definitions are stored in sys_ws_operation (Scripted REST API resources), sys_rest_message (REST Messages), and sys_soap_message (SOAP Messages). In scoped applications, web services are automatically namespaced and appear with the application scope prefix in their API paths and system names, but global web services can be accessed from any scope unless explicitly restricted.
How It Works Step by Step
Web services in ServiceNow operate through a request-response cycle that intercepts HTTP requests at the application server layer before standard UI processing begins. When an inbound API request arrives, ServiceNow first matches the request URL against registered Scripted REST API patterns, then authenticates the request using the configured authentication method (Basic Auth, OAuth 2.0, or mutual authentication certificates). The platform validates the user's permissions against any ACL rules defined for the specific API endpoint, then parses the request body and headers into JavaScript objects accessible within the web service script.
For outbound web service calls, the process begins when server-side code instantiates a REST Message or SOAP Message, typically triggered by business rules, scheduled jobs, or workflow activities. ServiceNow builds the HTTP request using the configured endpoint URL, headers, and request body template, then substitutes any parameter values provided by the calling script. The platform handles connection management, SSL certificate validation, and timeout settings automatically, while providing hooks for custom request modification through scripting.
Response processing includes automatic parsing of JSON and XML payloads into JavaScript objects, HTTP status code evaluation for error handling, and logging of the complete request-response cycle to system logs. The platform caches REST Message configurations and connection pools for performance, but individual responses are not cached unless explicitly implemented in custom code. Error handling follows a hierarchy where HTTP errors, parsing errors, and script execution errors are captured and can trigger custom error responses or retry logic.
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
- HTTP request arrives at ServiceNow application server and URL routing matches against registered Scripted REST API patterns
- Authentication validation occurs using configured method (Basic Auth extracts credentials, OAuth 2.0 validates bearer tokens)
- User session is established and ACL evaluation runs against the specific API endpoint and HTTP method
- Request headers and body are parsed into JavaScript objects accessible through
requestparameter - Scripted REST API resource script executes with full server-side API access and database connection
- Response object is constructed with status code, headers, and body content
- Complete request-response cycle is logged to
sys_rest_message_logtable with timing and payload data
(function process(request, response) {
try {
var requestBody = request.body.data;
var userSysId = requestBody.user_id;
// Validate required fields
if (!userSysId) {
response.setStatus(400);
response.setBody({error: 'user_id required'});
return;
}
// Query user record with security
var userGR = new GlideRecord('sys_user');
if (!userGR.get(userSysId)) {
response.setStatus(404);
response.setBody({error: 'User not found'});
return;
}
// Build response with controlled fields
var responseData = {
name: userGR.getDisplayValue('name'),
email: userGR.getDisplayValue('email'),
department: userGR.getDisplayValue('department')
};
response.setStatus(200);
response.setHeader('Content-Type', 'application/json');
response.setBody(responseData);
} catch (error) {
gs.error('API Error: ' + error.message);
response.setStatus(500);
response.setBody({error: 'Internal server error'});
}
})(request, response);Real-World Scenarios
Creating Employee Onboarding API for HR System Integration
Your HR system needs to automatically create ServiceNow user accounts when new employees are hired, including department assignment and role provisioning. The integration must validate employee data, create the user record, assign appropriate roles based on department, and return the new user's sys_id for downstream processing.
Create a new Scripted REST API at System Web Services > Scripted Web Services > Scripted REST APIs with Name set to 'HR Employee API' and API ID set to 'hr_employee'. Create a POST resource named 'create_user' with the script that validates required fields (employee_id, first_name, last_name, email, department), checks for duplicate users, creates the sys_user record, assigns roles based on department mapping, and returns structured JSON response with the new user's sys_id and assigned roles. Configure authentication to use Basic Auth with a dedicated integration user account.
Always validate email uniqueness before creating user records, as duplicate emails can cause authentication issues and break SSO integrations.
Pushing Incident Data to External Ticketing System
When incidents reach Priority 1 or 2, they must be automatically synchronized to your vendor's ticketing system for 24/7 support coverage. The integration needs to map ServiceNow incident fields to vendor API format, handle authentication tokens, and update the incident with the external ticket number.
Create a REST Message at System Web Services > Outbound > REST Message named 'Vendor Ticketing API' with endpoint URL pointing to the vendor's ticket creation API. Configure OAuth 2.0 authentication with client credentials flow, setting the Token URL, Client ID, and Client Secret fields. Create an HTTP Method 'POST' with request body template that maps incident fields to vendor format using variable substitution. Build a Business Rule on the incident table that triggers on Priority 1 or 2 incidents, instantiates the REST Message, populates the field mappings, executes the call, and updates the incident's u_external_ticket_number field with the response data.
Use the REST Message test functionality to validate authentication and field mapping before deploying the business rule to production.
Consuming Asset Data from Discovery Tool API
Your network discovery tool maintains the authoritative source of server configuration data that needs to be synchronized with ServiceNow's CMDB every hour. The integration must handle pagination, transform discovery tool data format to ServiceNow CI attributes, and implement proper error handling for network timeouts.
Configure a REST Message for the discovery tool's API with proper authentication and timeout settings of 60 seconds. Create a Script Include that handles the data retrieval logic, including pagination through multiple API calls using offset parameters, data transformation from discovery tool JSON format to ServiceNow CI fields, and error handling that logs failures but continues processing remaining records. Build a Scheduled Job that runs hourly, calls the Script Include, and processes the returned data by either updating existing CIs based on serial number matching or creating new cmdb_ci_server records. Implement proper logging to capture sync statistics, errors, and performance metrics.
Set appropriate timeout values for external API calls - network discovery tools often have slower response times than typical web services.
The Classic Mistake
Returning entire GlideRecord objects in Scripted REST APIs instead of serialized data.
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var incident = new GlideRecord('incident');
incident.get(request.pathParams.sys_id);
// WRONG: Returning GlideRecord object directly
var responseBody = {
incident: incident,
success: true
};
response.setStatus(200);
response.setHeader('Content-Type', 'application/json');
response.getStreamWriter().writeString(JSON.stringify(responseBody));
})(request, response);This approach fails because GlideRecord objects cannot be serialized to JSON and contain circular references that break JSON.stringify(). The API consumer receives malformed JSON or empty objects, while the ServiceNow logs show serialization errors. ServiceNow's JSON parser attempts to traverse the entire GlideRecord object graph, including internal references to the database connection and session state, which creates an infinite loop. This mistake is non-obvious because the code executes without throwing an exception, but the response payload is corrupted.
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var incident = new GlideRecord('incident');
incident.get(request.pathParams.sys_id);
// CORRECT: Extract specific field values
var responseBody = {
incident: {
sys_id: incident.getUniqueValue(),
number: incident.getValue('number'),
short_description: incident.getValue('short_description'),
state: incident.getDisplayValue('state'),
assigned_to: incident.getDisplayValue('assigned_to')
},
success: true
};
response.setStatus(200);
response.setHeader('Content-Type', 'application/json');
response.getStreamWriter().writeString(JSON.stringify(responseBody));
})(request, response);Always extract specific field values using getValue() or getDisplayValue() instead of returning GlideRecord objects in API responses.
When to Use This vs Alternatives
Web Services are the correct choice for real-time, bidirectional data exchange where you need immediate response validation and error handling. Use them when external systems need to query ServiceNow data on-demand or when ServiceNow must push critical updates that require acknowledgment from the receiving system.
Choose Web Services When
You need synchronous communication with immediate error handling, like LDAP authentication, credit card validation, or real-time inventory checks. Transform Maps and Import Sets fall short here because they're designed for batch processing and can't provide immediate feedback. MID Server connections work for discovery but lack the flexibility for custom business logic that Scripted REST APIs provide.
Use Alternatives When
You're moving large datasets or performing one-way data synchronization—use Import Sets with Transform Maps instead. For event-driven notifications without expecting a response, use Email Notifications or Business Rules that write to integration tables. When you need to poll external systems on a schedule, Scheduled Jobs calling REST Message records are more maintainable than complex Scripted REST APIs.
Combine With Other Tools When
You're building complex integrations that require both real-time validation and bulk data processing—use Web Services for the validation layer and Import Sets for the heavy lifting. Pair Scripted REST APIs with Business Rules when external systems need to trigger ServiceNow workflows but you also need to maintain audit trails and apply data validation rules. Always use Application Scopes to isolate custom APIs from platform APIs in the same namespace.
Platform Interactions & Side Effects
- Business Rules fire normally for database operations triggered by Web Services, but
current.operation()may return unexpected values in thebeforecontext - ACLs apply to Web Service operations, but the user context is the API user specified in the
sys_usertable, not the external system making the request - All API requests write entries to
syslogtable with sourcecom.glide.restand create session records insys_user_session - Scripted REST APIs execute in the application scope where they're defined, affecting which
Script IncludesandBusiness Rulesare accessible - Update Sets capture API definitions and scripts but not the data changes made through API calls, creating deployment gaps
- Web Service authentication bypasses MFA requirements but still respects password expiration policies in
sys_userrecords - Notifications triggered by API operations use the
glide.email.default_reply_tosystem property instead of user preferences - REST Message calls create entries in
ecc_queuethat consume processing threads and affect instance performance during high-volume operations - Transaction rollback in Scripted REST APIs affects all database operations within the request scope, not just the API response
- Cache invalidation occurs automatically when APIs modify cached table data, but custom cache keys in
GlideCacherequire manual management
Debugging and Troubleshooting
The most common failure symptoms include HTTP 500 Internal Server Error responses with no meaningful error message, authentication failures that return 401 Unauthorized despite correct credentials, and timeout errors when external systems don't respond. Users typically see generic error messages like "The request could not be processed" while admins see JavaScript exceptions in the application logs. Performance issues manifest as slow API responses or complete request timeouts, especially when processing large datasets or making multiple nested API calls within a single request.
Start troubleshooting in System Logs > All filtering by Source contains com.glide.rest for inbound API issues, and check REST Message Logs for outbound calls. Enable debug logging by setting com.glide.rest.debug to debug in System Properties. The most revealing error messages include "SecurityException: Access denied", "ReferenceError: [object] is not defined", and "JSONException: Expected literal value" which indicate permissions, scope, and serialization problems respectively.
Use the built-in REST API Explorer to test Scripted REST APIs directly from the ServiceNow interface, which bypasses authentication issues and provides immediate feedback on script errors. When debugging complex integrations, temporarily add gs.log() statements in your API scripts to trace execution flow, but remember to remove them before production deployment to avoid log pollution. External API testing tools like Postman reveal whether issues are in your ServiceNow configuration or the external system's implementation.
Diagnostic Checklist:
- Verify the API user has
rest_servicerole and ACL read access to all referenced tables - Check that Scripted REST API is
Active=trueand in correct application scope - Confirm
Content-Typeheader matches the data format being sent (application/json vs application/xml) - Test API endpoint with simple GET request before attempting complex POST/PUT operations
- Validate that REST Message
EndpointURL contains no extra spaces or special characters - Review
glide.outbound_http_log.enabled=truesystem property to capture full request/response details - Check session timeout settings if API calls work initially but fail after period of inactivity
Quick Reference
- Scripted REST APIs have 60-second execution timeout limit that cannot be extended, unlike Business Rules which timeout at 20 seconds
- REST Message response size limit is 5MB per call, but chunked responses can exceed this limit
- API versioning in Scripted REST requires creating entirely new API records—you cannot version individual resources within the same API
- OAuth 2.0 bearer tokens expire after 30 minutes by default, controlled by
oauth.access_token.lifetimesystem property - SOAP Web Services automatically generate WSDL documents but Scripted REST APIs require manual documentation creation
- Cross-origin requests require
glide.rest.cors.enabled=trueand explicitAccess-Control-Allow-Originheader configuration - Rate limiting is configured per user account, not per API endpoint, in the
sys_user_sessiontable - Basic Authentication credentials are cached for 5 minutes, causing delayed response to password changes
- Scripted REST API path parameters override URL query parameters when both contain the same parameter name
- JSON Web Service import requires valid SSL certificate on external endpoint, unlike REST Messages which can ignore certificate validation