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..keyor['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.