Using Advanced Queries in ServiceNow API
ServiceNow “WHERE” basics (Encoded Query)
In ServiceNow’s REST Table API, you pass a single string in sysparm_query that acts like a SQL WHERE clause. It’s called an encoded query.
Field + operator + value, joined by carets:
fieldOPvalue^field2OPvalue2...
AND is ^
OR is ^OR
Group ORs / separate disjoint clauses with ^NQ
You’ll typically also use helpful params like:
sysparm_fields=... (select columns)
sysparm_limit=... (row limit)
sysparm_display_value=true (return display values)
sysparm_exclude_reference_link=true (cleaner refs)
sysparm_query_no_domain=true (if you need to ignore domain separation)
Operator cheat-sheet
| Purpose | Encoded operator | Example |
|---|---|---|
| Equals | = | state=2 |
| Not equals | != | state!=6 |
| Greater / Less | >, <, >=, <= | priority<=2 |
| In list | IN (comma-sep) | priorityIN1,2,3 |
| Not in list | NOT IN | assignment_groupNOT INd625dc6c6fdd... |
| Contains (case-insens.) | LIKE or CONTAINS | short_descriptionLIKEemail |
| Starts with | STARTSWITH | caller_id.emailSTARTSWITHjohn |
| Ends with | ENDSWITH | u_reference_idENDSWITH-2025 |
| Empty / Not empty | ISEMPTY, ISNOTEMPTY | closed_atISEMPTY |
| Instance of (class) | INSTANCEOF | sys_class_nameINSTANCEOFtask |
| Between dates (via two ops) | >= and <= | sys_updated_on>=2025-08-01^sys_updated_on<=2025-08-23 23:59:59 |
Notes
• LIKE and CONTAINS are commonly used interchangeably for substring matches.
• Most text matching is case-insensitive.
• Values with spaces/special chars should be URL-encoded in the final request.
Building logic: AND, OR, grouping
AND (^)
active=true^priority<=2
OR (^OR)
priority=1^ORpriority=2
Tip: You can chain many ^OR... pieces.
Grouping with ^NQ
^NQ starts a new query clause that’s OR’ed with the previous entire clause. It’s the trick for “(A AND B) OR (C AND D)”.
(active=true^priority=1)^NQ(state=2^assignment_group=287ebd7da9fe198100f92cc8d1d2154e)
Read as: (active=true AND priority=1) OR (state=2 AND assignment_group=...).
Text operations & “wildcards”
You don’t use % or * with LIKE; the operator itself implies partial match.
Contains: short_descriptionLIKEemail
Starts with: u_ticket_idSTARTSWITHABC-
Ends with: u_ticket_idENDSWITH-42
Does not contain: short_descriptionDOESNOTCONTAINphish
If you must literally match special characters (like ^ inside a value), URL-encode them in the request. Inside ServiceNow’s list filters, you might see escaping with \; for REST, rely on URL encoding.
Dates & relative time
You can compare to absolute timestamps (in instance’s timezone) or use ServiceNow’s relative date macros:
Absolute
sys_updated_on>=2025-08-01 00:00:00^sys_updated_on<=2025-08-23 23:59:59
Relative (server-side JS macros)
sys_updated_on>=javascript:gs.daysAgoStart(7)
Common macros:
gs.daysAgoStart(n), gs.daysAgoEnd(n)
gs.beginningOfLastMonth(), gs.endOfLastMonth()
gs.hoursAgoStart(n), etc.
These are handy for “last 7 days”, “today”, “this month”, etc., without hardcoding dates.
More info on how to transform timestamps directly in Noreja can be found here.
Pagination, fields, and display values
Limit: sysparm_limit=100 (default is often 10)
Offset: sysparm_offset=0 (paginate yourself)
Fields: sysparm_fields=number,short_description,priority,state
Display values: sysparm_display_value=true to get human-friendly strings for references and choices.
Grouped logic with ^OR vs ^NQ
Using ^OR (within one group)
“Priority 1 OR 2, AND active”
priority=1^ORpriority=2^active=true
This is evaluated left-to-right with implicit ANDs between carets; ^OR has lower precedence than the explicit grouping you can achieve with ^NQ. In most real cases this behaves as intended.
Using ^NQ (between groups)
“(active AND priority 1) OR (state is On Hold AND updated last 7d)”
active=true^priority=1^NQstate=3^sys_updated_on>=javascript:gs.daysAgoStart(7)