The request.body.data property gives you the parsed JSON object from the request body—but only if ServiceNow successfully parsed it as JSON. Unlike other platforms where you get raw strings to parse yourself, ServiceNow pre-processes the body based on the Content-Type header. If the client sends malformed JSON or the wrong content type, request.body.data will be null or undefined with no helpful error message, leaving you debugging ghost requests that "aren't sending data" when they actually are—just not parseable.

When to use this pattern

  • Building REST endpoints that accept complex data structures with multiple fields or nested objects
  • Integrating with external systems that send JSON payloads for record updates or bulk operations
  • When you need both request body data and headers/query parameters for validation or audit trails
  • Processing webhook payloads from third-party services that follow REST conventions

When NOT to use this pattern

  • Don't build Scripted REST endpoints for ServiceNow-to-ServiceNow communication—use direct Script Include calls instead
  • Don't use this for simple GET operations with URL parameters—use query parameters with request.getParameter() instead
  • Don't process non-JSON payloads this way—for XML or form data, use request.body.dataString and parse manually
  • Don't use this for file uploads—ServiceNow Scripted REST APIs handle binary data differently through attachments

Key behaviors and gotchas

  • ServiceNow only populates request.body.data when Content-Type starts with application/json—other content types leave it undefined
  • The request.body.data object is already parsed—calling JSON.parse() on it will throw an error
  • Headers are case-insensitive when retrieved with request.getHeader(), but query parameters with request.getParameter() are case-sensitive
  • All inbound data is treated as strings initially—numeric field assignments like incident.state = requestBody.state work because ServiceNow coerces string values
  • Empty request bodies (Content-Length: 0) result in request.body.data being null, not an empty object
  • ACLs still apply to record operations within Scripted REST endpoints—test with users who have different role permissions
  • ServiceNow automatically logs failed JSON parse attempts in the system log with cryptic "REST API" entries
⚠️

Never trust request.body.data exists without checking—malformed JSON or missing Content-Type headers cause it to be null, and accessing properties on null crashes your endpoint with an unhelpful 500 error that makes debugging nearly impossible.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime