Best approach for ServiceNow to SQL Server/Data Warehouse integration for reporting
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi Community,
We're looking to extract data from ServiceNow into a SQL Server/Data Warehouse on a weekly basis for Power BI reporting. This is a read-only integration covering Incident, Catalog Task, Task SLA, and Survey Results data.
Would you recommend using the standard Table REST API or a Scripted REST API? Initial testing will use Basic Authentication.
Has anyone implemented a similar solution? What worked best in terms of performance, maintenance, and incremental data loads?
Thanks in advance for your recommendations and lessons learned.
Regards
CarolMa
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi @CarolMa6 ,
For a requirement like this, I would recommend using the standard Table REST API rather than a Scripted REST API.
Since you're extracting data from standard ServiceNow tables for reporting purposes only, the Table API is typically the most efficient and easiest solution to maintain. It already provides capabilities such as filtering, pagination, sorting, field selection, and incremental data extraction without requiring custom development.
A typical architecture would look like:
ServiceNow → SQL Staging Tables → Data Warehouse → Power BI
This keeps the integration layer simple and allows all reporting transformations to be handled within SQL Server or the Data Warehouse, which is generally a better practice than pushing reporting logic back into ServiceNow.
For your reporting requirements, you may want to extract data from tables such as:
- incident
- sc_task
- task_sla
- asmt_assessment_instance
- asmt_metric_result
- sys_user
- cmn_department
- cmdb_ci
Including some of the reference tables upfront can significantly reduce complex joins and lookups later in Power BI.
Incremental Loads
For performance reasons, I strongly recommend implementing incremental loads using the sys_updated_on field instead of performing full-table extracts every week.
For example:
Last successful extraction:
2026-07-25 00:00:00
Next extraction:
sys_updated_on > 2026-07-25 00:00:00
This approach:
Reduces API traffic
Minimizes impact on the ServiceNow instance
Improves ETL performance
Makes recovery easier if an extraction job fails
Performance Recommendations
A few lessons learned from similar ServiceNow-to-Data Warehouse integrations:
- Retrieve only the fields required for reporting using sysparm_fields.
Use pagination for large tables. - Avoid bringing back display values unless required (sysparm_display_value=false).
- Schedule extracts during off-peak hours where possible.
- For large tables such as Incident and Task SLA, incremental loads are critical to keep response times reasonable.
When Would a Scripted REST API Make Sense?
I would only consider a Scripted REST API if you need to:
- Combine multiple tables into a single payload
- Apply complex business logic before delivery
- Perform custom calculations
- Expose a reporting-specific data structure
For most Data Warehouse implementations, it's usually better to keep ServiceNow as the source and perform transformations within the ETL/Data Warehouse layer rather than customizing ServiceNow APIs.
Authentication
Basic Authentication is perfectly fine for initial testing. However, for production, I would recommend moving to OAuth 2.0 for improved security and easier credential management.
We've implemented similar ServiceNow-to-SQL reporting integrations using the standard Table API with incremental extraction based on sys_updated_on, and it has proven to be scalable, easier to support, and less maintenance-intensive than building and maintaining custom Scripted REST APIs.
Hope this helps and would be interested to hear what approach others in the community have adopted as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
