JSONPath: A Practical Guide to Querying JSON
June 19, 2026 · DevTools
JSON is easy for machines and verbose for humans. When a response nests five levels deep and you need "every email address in every order," writing the loop by hand gets old fast. JSONPath is a small query language for pointing at the parts of a JSON document you care about.
You can try every example below in the JSONPath Evaluator — it runs in your browser.
The sample document
{
"store": {
"book": [
{ "category": "reference", "author": "Nigel Rees", "title": "Sayings", "price": 8.95 },
{ "category": "fiction", "author": "Evelyn Waugh", "title": "Sword", "price": 12.99 },
{ "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "price": 8.99 }
],
"bicycle": { "color": "red", "price": 19.95 }
}
}
The root and dot notation
$ is the root object. Navigate with dots:
$.store.bicycle.color→"red"$.store.book[0].author→"Nigel Rees"$.store.book[1].title→"Sword"
Bracket notation
Use brackets when keys contain odd characters or when you want an index:
$['store']['book'][2]['price']→8.99$.store.book[-1]→ the last book (negative indexing, supported by most implementations)
Wildcards
* matches "everything at this level":
$.store.book[*].author→ all authors:["Nigel Rees", "Evelyn Waugh", "Herman Melville"]$.store.*→ thebookarray and thebicycleobject
Recursive descent
.. means "search at any depth." This is the one people reach for most:
$..author→ every author, anywhere in the tree$..price→ every price, including the bicycle's$..book[0]→ the first book found at any depth
Array slices
Slice arrays Python-style:
$.store.book[0:2]→ first two books$.store.book[1:]→ everything from index 1 onward$.store.book[::-1]→ the books reversed
Filter expressions
Filters narrow results with a test in [?(...)]. Inside, @ refers to the current element:
$..book[?(@.price < 10)]→ books cheaper than 10$..book[?(@.category == 'fiction')]→ only fiction$..book[?(@.author =~ /melville/i)]→ regex match on author
Two things that trip people up
- JSONPath has no single spec. RFC 9535 (JSONPath) standardized the basics recently, but older libraries (Stefan Goessner's original, Jayway, jsonpath-plus) differ on filters, regex, and functions. If an expression works in one tool and not another, this is usually why.
- Filters can't sort or aggregate. JSONPath selects; it doesn't compute sums or reorder. Sort the results in your own code.
When to reach for JSONPath
JSONPath shines for ad-hoc extraction — digging a value out of an unfamiliar API response, or pulling many matching values without writing traversal code. For heavy, repeated transforms you'll want JMESPath or a real query layer, but for "give me every price under 10," JSONPath is the right tool.
Paste a document and an expression into the JSONPath Evaluator, and tidy messy input first with the JSON Formatter.