ServiceNow Table API: Complete Developer Reference

The Table API is ServiceNow's most used REST endpoint — it exposes every table in the platform via standard HTTP methods and allows external systems to read, create, update, and delete records. This complete reference covers every operation, all query parameters, both authentication methods, pagination, display values vs raw values, error handling, and the patterns used in production integrations.

Base URL

https://[instance].service-now.com/api/now/table/[table_name]

// Examples:
https://mycompany.service-now.com/api/now/table/incident
https://mycompany.service-now.com/api/now/table/sys_user
https://mycompany.service-now.com/api/now/table/cmdb_ci_server

Authentication

OAuth 2.0 (recommended for production)

// Step 1: Get access token
POST /oauth_token.do
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=YOUR_ID&client_secret=YOUR_SECRET

// Step 2: Use the token
GET /api/now/table/incident
Authorization: Bearer eyJhbGc...

Basic Authentication

// Base64-encode username:password
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

// Never use a named user's credentials — always create a dedicated integration user
// with only the roles required for the integration

GET — retrieve multiple records

GET /api/now/table/incident
  ?sysparm_query=active=true^priority=1^state!=6
  &sysparm_limit=50
  &sysparm_offset=0
  &sysparm_fields=number,short_description,state,assigned_to,priority
  &sysparm_display_value=true
  &sysparm_exclude_reference_link=true

Authorization: Bearer [token]

Complete query parameter reference

ParameterDescriptionExample
sysparm_queryEncoded query — same syntax as GlideRecordactive=true^priority=1
sysparm_limitMax records to return (default 10, max 10000)100
sysparm_offsetNumber of records to skip (for pagination)100
sysparm_fieldsComma-separated list of fields to returnnumber,state,assigned_to
sysparm_display_valuetrue=display values, false=raw, all=bothtrue
sysparm_exclude_reference_linkRemove link objects from reference fieldstrue
sysparm_viewForm view to use for determining fieldsdesktop
sysparm_suppress_auto_sys_fieldExclude sys_created_on etc. from responsetrue

GET — retrieve single record by sys_id

GET /api/now/table/incident/6816f79cc0a8016401c5a33be04be441
  ?sysparm_display_value=true
  &sysparm_fields=number,short_description,state,resolved_at

// Response: 200 OK with single record object (not an array)

GET — retrieve by unique field value

GET /api/now/table/incident
  ?sysparm_query=number=INC0001234
  &sysparm_limit=1

// Or using the Table API's field-specific lookup:
GET /api/now/table/incident?number=INC0001234

POST — create a record

POST /api/now/table/incident
Content-Type: application/json
Authorization: Bearer [token]

{
  "short_description": "Printer not working in Finance",
  "urgency": "2",
  "impact": "2",
  "category": "hardware",
  "subcategory": "printer",
  "caller_id": "6816f79cc0a8016401c5a33be04be441"
}

// Response: 201 Created
{
  "result": {
    "sys_id": "abc123...",
    "number": "INC0001234",
    "short_description": "Printer not working in Finance",
    ...
  }
}

Reference fields (like caller_id) accept sys_ids. Do not pass display values — they will fail. Retrieve the sys_id first if you only have the display value.

PATCH — update specific fields

PATCH /api/now/table/incident/[sys_id]
Content-Type: application/json
Authorization: Bearer [token]

{
  "state": "6",
  "close_code": "Solved (Permanently)",
  "close_notes": "Replaced printer cartridge. Printer working normally."
}

// Response: 200 OK with the updated record
// Only the fields you send are updated — others remain unchanged

PUT — replace entire record

PUT /api/now/table/incident/[sys_id]
Content-Type: application/json
Authorization: Bearer [token]

// PUT replaces the entire record — fields not included are cleared to default
// Use PATCH in almost all cases — PUT is destructive for fields you don't include

{
  "short_description": "Updated description",
  "state": "2",
  // All other fields not included here will be cleared
}

DELETE — remove a record

DELETE /api/now/table/incident/[sys_id]
Authorization: Bearer [token]

// Response: 204 No Content
// This is a hard delete — use carefully
// The calling user needs delete ACL access to the record

Pagination

// Page 1 — first 100 records
GET /api/now/table/incident?sysparm_limit=100&sysparm_offset=0

// Page 2 — next 100 records
GET /api/now/table/incident?sysparm_limit=100&sysparm_offset=100

// Page 3
GET /api/now/table/incident?sysparm_limit=100&sysparm_offset=200

// Check X-Total-Count response header to know total records
// X-Total-Count: 1247
// Calculate last page: Math.ceil(1247 / 100) = 13 pages

Display values vs raw values

// sysparm_display_value=false (default)
// Reference fields return sys_id
// Choice fields return stored value (e.g. "1" for "New")
{
  "state": "1",
  "assigned_to": { "value": "6816f79c...", "link": "..." }
}

// sysparm_display_value=true
// Reference fields return display name
// Choice fields return display label
{
  "state": "New",
  "assigned_to": { "display_value": "John Smith", "link": "..." }
}

// sysparm_display_value=all
// Returns both value and display_value for every field
{
  "state": { "value": "1", "display_value": "New" },
  "assigned_to": { "value": "6816...", "display_value": "John Smith" }
}

Error codes and handling

// 200 OK — GET/PATCH successful
// 201 Created — POST successful, check Location header
// 204 No Content — DELETE successful
// 400 Bad Request — malformed JSON, invalid field values
// 401 Unauthorized — invalid or expired token
// 403 Forbidden — authenticated but no ACL access
// 404 Not Found — record or table does not exist
// 429 Too Many Requests — rate limited, check Retry-After header
// 500 Internal Server Error — server-side error

// Good error handling in consuming code:
async function getIncident(sysId) {
  const response = await fetch(`/api/now/table/incident/${sysId}`, {
    headers: { 'Authorization': `Bearer ${token}` }
  });

  if (response.status === 404) return null;
  if (response.status === 401) { await refreshToken(); return getIncident(sysId); }
  if (!response.ok) throw new Error(`API error: ${response.status}`);

  const data = await response.json();
  return data.result;
}

Related guides:

Table API query patterns

The Table API's sysparm_query parameter accepts encoded query syntax — the same syntax you use in GlideRecord's addEncodedQuery(). This makes it straightforward to build targeted queries: active=true^priority=1^state!=6. Combined with sysparm_fields (specify only the fields you need) and sysparm_limit (bound the result set), you can build efficient, focused API calls:

// Example: Get active P1 incidents, specific fields only
GET /api/now/table/incident
  ?sysparm_query=active%3Dtrue%5Epriority%3D1%5Estate%216
  &sysparm_fields=number,short_description,assignment_group,opened_at
  &sysparm_limit=50
  &sysparm_display_value=false

The sysparm_display_value parameter controls whether the API returns raw values (sys_ids for reference fields) or display values (user-facing labels). Setting it to false returns raw values — more efficient and less prone to locale-related inconsistencies. Set to true for integrations that need human-readable values. Set to all to get both — the response includes both value and display_value for each field.

Table API authentication options

The Table API supports three authentication methods: Basic Authentication (username/password — fine for development, not recommended for production), OAuth 2.0 (recommended for production integrations), and Integration User with limited role (a service account with only the roles needed for the integration). For production integrations, create a dedicated integration user with only the roles required — typically a custom role that grants read or write access only to the specific tables the integration uses. This follows the principle of least privilege and makes security auditing simpler.

See OAuth 2.0 guide for setting up OAuth for the Table API · ServiceNow REST API overview · Building custom REST endpoints · Credential Aliases

For the topics covered in this guide, the most effective way to deepen your knowledge is hands-on practice on a Personal Developer Instance (PDI). ServiceNow provides free PDIs to all registered developers — request yours at developer.servicenow.com if you do not already have one. A PDI lets you experiment with configurations, break things safely, test edge cases, and build portfolio examples that you can demonstrate in interviews. Every senior ServiceNow practitioner has spent hundreds of hours on their PDI. It is the irreplaceable complement to reading guides like this one.

The weekly NowSpectrum newsletter delivers one focused, practical tip per week to your inbox — subscribe free at newsletter.nowspectrum.com. Each issue covers a specific pattern, common mistake, or practical technique relevant to working ServiceNow professionals. The archive covers every major platform area and makes for useful reference material when you encounter unfamiliar territory in a new project.

Building robust external integrations with the Table API

The Table API is the most commonly used ServiceNow REST endpoint for external system integrations. Systems that need to create incidents, query CIs, update users, or read service catalog data typically do so via the Table API. Building a robust integration means handling not just the happy path but also rate limiting (ServiceNow applies rate limits — handle 429 responses with exponential backoff), authentication expiry (OAuth tokens expire — handle 401 responses by refreshing the token), large result sets (use pagination with sysparm_offset to handle results that exceed the limit), and errors (check the response status code and the error property in the response body). Integrations that do not handle these cases will fail in production under load or over time as tokens expire. The Table API documentation covers all response codes and error formats — build your integration against the full specification, not just the success cases.

The ServiceNow platform rewards practitioners who invest in deep, systematic knowledge rather than surface-level familiarity with every feature. The guides in this series are designed to build that depth — covering not just the API surface but the underlying mechanics, the common mistakes, the performance implications, and the architectural patterns that experienced developers and admins have learned through production work. Use this guide as a starting point and return to it as your experience deepens — concepts that are abstract when you first read them often become clear once you have encountered the problem they solve in a real implementation. The NowSpectrum free weekly newsletter delivers one practical insight per week, and the product library at store.nowspectrum.com offers deeper reference materials including interview prep kits, API cheat sheets, and comprehensive guides for each major ServiceNow domain. Combined with hands-on practice on your Personal Developer Instance, systematic study of platform fundamentals, and engagement with the ServiceNow community, you have everything you need to build the expertise that commands the highest compensation and most interesting work in the ecosystem.

See the full integration series: ServiceNow REST API guide covering all available APIs and when to use each one, building custom Scripted REST APIs for cases where the Table API does not provide the right interface, OAuth 2.0 configuration for secure authentication, and Connection and Credential Aliases for managing integration credentials at scale across multiple environments and integrations.

Table API pagination for large result sets

The Table API has a maximum limit per request (typically 10,000 records, though the recommended practice is 100–500 for performance). For result sets larger than the limit, use pagination: include sysparm_offset and sysparm_limit parameters, and check the X-Total-Count response header to know the total record count. Increment offset by limit on each page until offset exceeds total count. For integrations that process large record sets, combine pagination with a Scheduled Job or queue-based architecture to avoid timeout failures on the calling system.

The complete integrations reference

The NowSpectrum Integrations Complete Reference Guide — 26 pages covering REST API, Table API, OAuth 2.0, MID Server, and 50 interview Q&As.

Get the Integrations Guide →
← Back to all posts