The ServiceNow SAP Concur integration automates expense management workflows by creating service requests from expense events, synchronizing travel policies, and surfacing expense reports within ServiceNow. This integration solves the business problem of manual expense processing and policy compliance by enabling HR and Finance teams to manage employee expenses directly within their ServiceNow instance. The integration supports bi-directional data flow with ServiceNow consuming expense data, travel policies, and user information from Concur while pushing approval statuses and policy updates back to Concur. The primary automation pattern uses scheduled imports and event-driven webhooks to trigger workflows in the Service Request Management and HR Service Delivery modules.
Prerequisites
- •ServiceNow Vancouver or later with Integration Hub Professional license
- •SAP Concur Professional or Premium subscription with API access enabled
- •System Administrator role in ServiceNow with integration_user_role
- •Concur Implementation Manager or Web Services Admin role in SAP Concur
- •Active MID Server with outbound internet connectivity for real-time webhook processing
- •HR Service Delivery plugin (com.sn_hr_service_delivery) activated
- •Service Request Management plugin (com.snc_service_request_management) activated
Architecture Overview
The integration leverages the ServiceNow Integration Hub SAP Concur spoke along with custom REST Message records for advanced API calls not covered by the spoke actions. Authentication is established using OAuth 2.0 Client Credentials flow with credentials stored in Connection & Credential Aliases under the Connections & Credentials module. Data flows uni-directionally from Concur to ServiceNow for expense reports and bi-directionally for policy data and approval statuses, triggered by scheduled jobs and real-time webhooks processed through a MID Server. The MID Server is required for webhook processing and outbound API calls due to Concur's IP whitelisting requirements and the need for consistent outbound IP addresses. Rate limiting considerations include Concur's standard 1000 API calls per hour per application, requiring implementation of retry logic and request queuing in ServiceNow scheduled jobs.
Sourdough: ServiceNow Monitoring and Analytics
A Chrome extension for ServiceNow Admins and Developers with essential tools, analytics, graphs and monitoring features.
Free to install. Pro $5/month after a 14-day no-card trial.
Pro requires the ServiceNow admin role. Upgrade inside the extension.
Implementation Steps
Configure SAP Concur API application and obtain OAuth credentials
Log into SAP Concur as a Web Services Administrator and navigate to Administration > Web Services > Register Partner Application. Create a new application with the name 'ServiceNow Integration' and select the required scopes: expense.report.read, travel.profile.read, and expense.policy.read. Record the Client ID and Client Secret provided after application creation. Ensure the application is approved by your Concur administrator before proceeding, as unapproved applications cannot authenticate successfully.
Create Connection and Credential records in ServiceNow
Navigate to Connections & Credentials > Connections and create a new connection named 'SAP Concur Production' with the connection URL set to your Concur instance (e.g., https://us.api.concursolutions.com). Create a new OAuth 2.0 credential by navigating to Connections & Credentials > Credentials, selecting OAuth 2.0 Entity Credentials, and entering the Client ID and Client Secret from Concur. Set the OAuth Entity Profile to use the Token URL https://us.api.concursolutions.com/oauth2/v0/token and configure the Grant Type as Client Credentials. Test the credential by clicking 'Get OAuth Token' to verify successful authentication.
Install and configure the SAP Concur Integration Hub spoke
Navigate to System Applications > All Available Applications > All and search for 'SAP Concur' to locate the official Integration Hub spoke. Install the spoke and navigate to Process Automation > Flow Designer to create a new flow. Add the SAP Concur spoke actions including 'Get Expense Reports', 'Get User Profile', and 'Update Report Approval Status' to your flow canvas. Configure each action to use the Connection and Credential created in the previous step, ensuring proper error handling is enabled for each action.
Create custom REST Message for advanced Concur API operations
Navigate to System Web Services > Outbound > REST Messages and create a new REST Message named 'Concur Advanced API'. Set the endpoint to https://us.api.concursolutions.com and create HTTP methods for 'GetExpenseEntries', 'GetTravelPolicies', and 'UpdateExpenseReport'. Configure each method to use the OAuth credential created earlier and set appropriate headers including 'Accept: application/json' and 'Concur-CorrelationId: ServiceNow-${sys_id}'. Add authentication headers by referencing the credential alias in the Authentication tab.
// REST Message HTTP Method configuration for GetExpenseEntries
var request = new sn_ws.RESTMessageV2('Concur Advanced API', 'GetExpenseEntries');
request.setStringParameterNoEscape('user_id', current.u_employee_number);
request.setStringParameterNoEscape('report_id', current.u_concur_report_id);
request.setRequestHeader('Concur-CorrelationId', 'ServiceNow-' + current.sys_id);
var response = request.execute();
if (response.getStatusCode() == 200) {
var responseBody = response.getBody();
var expenseData = JSON.parse(responseBody);
return expenseData;
} else {
gs.error('Concur API Error: ' + response.getStatusCode() + ' - ' + response.getBody());
}Create custom tables and configure data mapping for expense reports
Navigate to System Definition > Tables and create a new table named 'u_concur_expense_report' extending the Service Request table (svc_request). Add custom fields including u_concur_report_id (string), u_total_amount (currency), u_expense_type (choice), u_approval_status (choice), and u_employee_number (reference to User table). Create a second table 'u_concur_expense_line_item' with fields for line item details and a reference back to the expense report. Configure choice lists for expense types and approval statuses to match your Concur configuration, ensuring data consistency between systems.
Build scheduled job to sync expense reports from Concur
Navigate to System Definition > Scheduled Jobs and create a new scheduled job named 'Concur Expense Report Sync' that runs every 15 minutes. Write a script that calls the Concur API to retrieve expense reports modified in the last hour, then creates or updates corresponding records in the u_concur_expense_report table. Include error handling to manage API rate limits and network timeouts, logging all activities to the system log for troubleshooting. Implement a checkpoint mechanism using system properties to track the last successful sync timestamp and avoid duplicate processing.
// Scheduled Job script for syncing Concur expense reports
var concurAPI = new sn_ws.RESTMessageV2('Concur Advanced API', 'GetExpenseReports');
var lastSync = gs.getProperty('concur.last_sync_time', gs.dateGenerate(gs.daysAgoStart(1)));
concurAPI.setStringParameterNoEscape('modifiedafter', lastSync);
var response = concurAPI.execute();
if (response.getStatusCode() == 200) {
var reports = JSON.parse(response.getBody()).Items;
var processed = 0;
reports.forEach(function(report) {
var gr = new GlideRecord('u_concur_expense_report');
gr.addQuery('u_concur_report_id', report.ID);
gr.query();
if (!gr.next()) {
gr.initialize();
gr.u_concur_report_id = report.ID;
gr.short_description = 'Expense Report: ' + report.Name;
}
gr.u_total_amount = report.Total;
gr.u_approval_status = report.ApprovalStatusCode;
gr.state = mapConcurStatusToSNState(report.ApprovalStatusCode);
gr.update();
processed++;
});
gs.setProperty('concur.last_sync_time', new GlideDateTime().getDisplayValue());
gs.info('Processed ' + processed + ' Concur expense reports');
} else {
gs.error('Concur sync failed: ' + response.getStatusCode());
}Configure webhook endpoint for real-time expense report notifications
Navigate to System Web Services > Scripted Web Services > Scripted REST APIs and create a new API named 'ConcurWebhookHandler' with a resource for POST requests. Implement the resource to process incoming webhook payloads from Concur, validate the request using HMAC signature verification, and trigger appropriate workflows based on the event type. Configure your MID Server to handle the webhook processing by ensuring it can accept inbound connections on the designated port. Register the webhook URL (https://your-instance.service-now.com/api/now/concur/webhook) in your Concur Web Services configuration, specifying events for expense report submissions and approvals.
// Scripted REST API Resource for Concur webhooks
(function process(request, response) {
var requestBody = request.body.dataString;
var signature = request.getHeader('X-Concur-Signature');
// Validate webhook signature
var expectedSignature = gs.generateHMAC('HmacSHA256', requestBody, gs.getProperty('concur.webhook.secret'));
if (signature !== expectedSignature) {
response.setStatus(401);
response.setBody('Invalid signature');
return;
}
var webhookData = JSON.parse(requestBody);
if (webhookData.eventType === 'expense.report.submit') {
var gr = new GlideRecord('u_concur_expense_report');
gr.addQuery('u_concur_report_id', webhookData.data.reportId);
gr.query();
if (gr.next()) {
gr.state = 'submitted_for_approval';
gr.update();
// Trigger approval workflow
var workflow = new Workflow();
workflow.startFlow('expense_approval_flow', gr.sys_id);
}
}
response.setStatus(200);
response.setBody('Processed');
})(request, response);Test integration and configure monitoring dashboards
Execute the scheduled job manually from System Definition > Scheduled Jobs to verify expense reports are successfully imported from Concur and mapped to ServiceNow records. Test the webhook endpoint using Concur's webhook testing tool or a REST client like Postman to ensure real-time notifications are processed correctly. Create a dashboard in Performance Analytics or configure reports in System Reporting to monitor integration health, including API response times, error rates, and sync completion status. Set up email notifications for integration failures by creating event rules that trigger when the scheduled job fails or webhook processing encounters errors.
Common Use Cases
Automated expense report approval workflows
When employees submit expense reports in Concur, webhooks trigger ServiceNow workflows to route approvals based on amount thresholds and organizational hierarchy. The system automatically creates approval requests in ServiceNow, sends notifications to managers, and updates approval status back to Concur upon completion. This eliminates manual approval routing and ensures consistent policy enforcement across both systems while providing audit trails in ServiceNow.
Travel policy violation incident creation
Integration monitors expense reports for policy violations detected by Concur and automatically creates incidents in ServiceNow for HR investigation. The system captures violation details, supporting documentation, and employee information to streamline the review process. HR agents can document their findings, communicate with employees through ServiceNow, and track resolution metrics for compliance reporting.
Employee onboarding expense account setup
When new employees are created in ServiceNow's HR system, automated workflows trigger Concur API calls to provision expense accounts and assign appropriate travel policies. The integration ensures consistent account setup, applies correct approval hierarchies, and validates that all required fields are populated. This reduces manual setup time and eliminates errors in employee expense account configuration.
Expense report analytics and compliance monitoring
ServiceNow imports detailed expense line items from Concur to enable advanced analytics and compliance reporting through Performance Analytics. The system tracks spending patterns, identifies anomalies, and generates executive dashboards showing expense trends by department, project, or employee. This provides deeper insights than Concur's standard reporting while maintaining data consistency for financial auditing.
Service request automation for expense-related issues
Integration creates service requests automatically when employees encounter issues with expense submissions or reimbursements in Concur. The system captures error details, expense report information, and employee context to enable faster resolution by finance teams. Automated categorization and routing ensure requests reach the appropriate resolver groups while maintaining SLA compliance and user satisfaction metrics.
Troubleshooting
OAuth token expiration causing 401 Unauthorized errors
Check the System Log for authentication failures and navigate to Connections & Credentials > Credentials to test token refresh. Click 'Get OAuth Token' on your Concur credential to manually refresh the token and verify connectivity. If automatic token refresh fails, verify that the MID Server has outbound internet access and that Concur's token endpoint URL is correctly configured in the credential record.
Webhook payloads received but no ServiceNow records created
Navigate to System Logs > System Log > All to check for webhook processing errors and verify that the HMAC signature validation is passing. Review the Scripted REST API execution logs under System Web Services > Scripted Web Services > Scripted REST APIs and check the resource execution history. Ensure the webhook secret property matches the value configured in Concur and that the JSON payload structure matches your parsing logic.
Scheduled job failing with timeout errors during large data imports
Review the scheduled job execution history under System Definition > Scheduled Jobs and check for timeout patterns during peak usage periods. Implement pagination in your API calls by adding limit and offset parameters to process smaller batches of records. Consider breaking large sync operations into multiple smaller scheduled jobs or implementing a queue-based processing system using the Event Management module to handle high-volume data imports.
Concur API rate limit exceeded errors (429 status code)
Implement exponential backoff retry logic in your REST Message scripts and reduce the frequency of scheduled job execution during peak hours. Monitor API usage patterns in the Outbound HTTP Request Log under System Web Services > Outbound > HTTP Request Logs. Add delays between API calls and implement a token bucket algorithm to stay within Concur's 1000 requests per hour limit, spreading requests evenly throughout the hour.
Expense report data mapping inconsistencies between systems
Create a data mapping document that defines how Concur fields map to ServiceNow fields and implement validation rules in your import scripts. Use transform maps with field mapping and data transformation functions to handle currency conversions, date format differences, and choice list value mappings. Regularly audit imported data by creating reports that compare record counts and key field values between systems to identify mapping issues early.
MID Server connectivity issues preventing webhook processing
Verify that the MID Server can establish outbound HTTPS connections to Concur's API endpoints by testing connectivity from the MID Server Status page. Check firewall rules to ensure the MID Server's outbound IP addresses are whitelisted in Concur's security settings. Review MID Server logs for SSL certificate validation errors and ensure that corporate proxy settings are properly configured if your environment requires proxy authentication for external API access.
Pro Tips
- →Implement custom business rules on the expense report table to automatically assign categories and priorities based on amount thresholds and expense types, improving routing efficiency and SLA management. Use dot-walking in your business rules to access related employee data like department and manager information for intelligent assignment logic.
- →Create a custom application with dedicated modules for expense management to provide users with streamlined views of their expense requests and approval status. Include custom UI actions that allow managers to approve expenses directly from ServiceNow while maintaining integration with Concur's approval workflow through API callbacks.
- →Set up Performance Analytics widgets to track expense processing metrics including average approval times, policy violation rates, and integration health indicators. Configure automated alerting when API error rates exceed acceptable thresholds or when expense report processing falls behind schedule.
- →Implement field-level encryption for sensitive expense data like personal credit card information or detailed receipt data stored in ServiceNow. Use the Edge Encryption proxy to encrypt data at rest while maintaining searchability for reporting and analytics purposes.
- →Configure Connection & Credential Aliases with multiple failover endpoints to handle Concur data center outages or maintenance windows. Implement circuit breaker patterns in your integration code to automatically switch to secondary endpoints when primary connections fail.
- →Create custom update sets specifically for Concur integration components to streamline deployment across development, test, and production environments. Include all related tables, business rules, scheduled jobs, and credentials in a single update set for consistent deployment practices.
Known Limitations
- —The SAP Concur API enforces a rate limit of 1000 requests per hour per application, which may constrain real-time synchronization for large organizations with high expense report volumes. This requires implementing queuing mechanisms and spreading API calls across longer time windows to avoid throttling.
- —Concur's webhook delivery mechanism does not guarantee ordered delivery of events, potentially causing race conditions when processing rapid status changes on the same expense report. ServiceNow implementations must include logic to handle out-of-order webhook processing and maintain data consistency.
- —The Integration Hub SAP Concur spoke requires an Integration Hub Professional license and supports a limited subset of Concur's API endpoints, necessitating custom REST Message implementations for advanced features like detailed expense line item retrieval or custom field synchronization. This increases development complexity and maintenance overhead.
- —Real-time bidirectional synchronization is not fully supported due to Concur's API architecture, which may result in temporary data inconsistencies between systems during high-volume processing periods. Critical approval decisions should include manual verification steps to ensure data accuracy.
- —MID Server dependency for webhook processing and outbound API calls adds infrastructure complexity and potential points of failure. Organizations must maintain high availability MID Server configurations and monitor connectivity to prevent integration disruptions during network outages or maintenance windows.
Frequently Asked Questions
Can I sync historical expense data from Concur when first setting up the integration?
Yes, but you'll need to implement a one-time data migration process that respects Concur's API rate limits. Create a separate scheduled job that processes historical data in batches, using date range parameters to retrieve expense reports from specific time periods. Consider running this migration during off-peak hours and implement checkpointing to resume processing if interrupted. The standard sync job should be disabled during historical data migration to prevent conflicts.
How do I handle currency conversion when syncing expense reports with multiple currencies?
ServiceNow can leverage Concur's built-in currency conversion data through the API, which includes both original amounts and converted values. Configure your expense report table to store both the original currency amount and the converted amount in your organization's base currency. Use ServiceNow's Currency plugin to maintain exchange rate tables and implement business rules that validate currency conversions match between systems for audit compliance.
What happens if ServiceNow is unavailable when Concur sends webhook notifications?
Concur will retry webhook delivery according to its retry policy (typically 3-5 attempts with exponential backoff), but failed webhooks are not queued indefinitely. Implement a reconciliation process using scheduled jobs that periodically compares expense report modification timestamps between systems to catch any missed webhook events. Consider using ServiceNow's Event Management module to queue webhook processing and ensure reliable delivery even during system maintenance windows.
Can I customize the approval workflow in ServiceNow while maintaining synchronization with Concur?
Yes, you can implement custom approval workflows in ServiceNow as long as you maintain bidirectional status synchronization with Concur through API calls. Design your workflow to update Concur's approval status when ServiceNow approvals are completed, and handle conflicts when approvals occur simultaneously in both systems. Use ServiceNow's Workflow Editor or Flow Designer to create approval processes that call Concur's approval APIs as part of the workflow execution.
How do I handle Concur sandbox and production environments in my ServiceNow integration?
Create separate Connection and Credential records for each Concur environment, using naming conventions like 'Concur Sandbox' and 'Concur Production'. Implement system properties or configuration records to control which Concur environment your integration targets, allowing easy switching between environments for testing. Use ServiceNow's update set promotion process to move integration configurations between instances while maintaining environment-specific connection details.
What ServiceNow roles and permissions are needed for users to access integrated expense data?
Users need the 'sn_request_read' role to view expense service requests and custom roles for accessing expense report tables you create. Create a dedicated role like 'concur_expense_user' that includes read access to expense tables and related modules, then assign this role based on organizational hierarchy. Implement Access Control Rules (ACLs) that restrict expense report visibility to the submitting employee, their managers, and finance team members to maintain data privacy and compliance.
How can I troubleshoot data mapping issues when expense categories don't match between systems?
Create a mapping table in ServiceNow that translates Concur expense categories to ServiceNow values, allowing for flexible configuration without code changes. Implement data validation rules that flag unmapped categories and create incidents for administrators to review. Use Transform Maps with custom transformation scripts to handle complex category mappings and consider implementing fuzzy matching algorithms for similar category names. Regularly audit category usage through reports to identify new categories that need mapping configuration.
Test Your Knowledge
Quick 3-question quiz — see how your ServiceNow skills stack up.
A list view on a table with millions of records is slow. Best fix?
Select an answer to continue