JSONPath

JSONPath is a query syntax for selecting values inside a JSON document. An expression starts at the root, $, and steps through keys and array indexes until it reaches what you want.

{
  "service": "checkout",
  "checks": [
    { "name": "smoke", "ok": true },
    { "name": "migrations", "ok": true },
    { "name": "canary", "ok": false, "error": "timeout" }
  ],
  "headers": { "content-type": "application/json" }
}
Expression Selects
$.service "checkout"
$.checks[2].error "timeout"
$.checks[*].name "smoke", "migrations", "canary"
$.checks[-1] the last check
$.checks[0:2] the first two checks (slice, end excluded)
$..name every name, at any depth
$.checks[?@.ok == false] checks whose ok is false
$.headers['content-type'] "application/json"

Proposed by Stefan Goessner in 2007 as "XPath for JSON", it spread through dozens of slightly different libraries before the IETF standardised it as RFC 9535 in 2024. Older libraries may write the filter as [?(@.ok == false)]; the parentheses are optional in the RFC.

The pieces

  • $ — the root. Every expression begins here.
  • .key or ['key'] — a child by name. Use the bracket form when the key has a hyphen, a space, or starts with a digit.
  • [n] — an array element. Negative indexes count from the end.
  • [*] — every child, of an object or an array.
  • .. — recursive descent: look at this level and every level below.
  • [start:end:step] — an array slice.
  • [?…] — a filter; @ is the element being tested.

A JSONPath query returns a list of matches, possibly empty. A path that names one specific value — no wildcards, no filters — is called a normalized path, and it is what you usually want to copy into a test or a log line.

JSONPath, JSON Pointer and jq

Three syntaxes point into JSON, and they are not interchangeable.

Need Syntax Same location
Query, possibly many values JSONPath $.checks[2].error
Address exactly one value (JSON Patch, $ref) JSON Pointer (RFC 6901) /checks/2/error
Transform on the command line jq .checks[2].error
Plain code JavaScript data.checks[2].error

PostgreSQL's jsonb_path_query uses the SQL/JSON path language, which also starts at $ and reads much like JSONPath, but its filter syntax and functions are its own.

Getting the path without writing it

Hand-writing a path into a five-level API response is where the typos come from — an off-by-one index, a key with a hyphen left unquoted. Easier to click the value and copy the path. The free JSON viewer shows a payload as a collapsible tree; click any node and it gives you the JSONPath and the JavaScript/jq accessor, with keys like content-type already bracket-quoted.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Open the JSON viewer →

Related