JSONPath Tester

Paste JSON, write a JSONPath expression, and every match appears live — each one labelled with the exact path it was found at, so you can see where the data came from and not just what it is. Nothing leaves your browser.


        
      

JSONPath syntax supported by this tool

JSONPath is to JSON roughly what XPath is to XML: a compact expression language for pulling values out of a nested document. It is what kubectl -o jsonpath, Kubernetes, Jenkins, Azure CLI, Postman assertions, Elasticsearch ingest pipelines and most API-testing frameworks use under the hood. This page implements the widely-used subset those tools share.

ExpressionMeaningExample
$The root of the document. Optional — a leading bare key works too.$.store
.keyChild by name.$.store.bicycle
['key']Child by name, for keys with spaces, dashes or dots.$['order-id']
*Wildcard — every value at this level.$.store.*
..keyRecursive descent: find key at any depth.$..price
[n]Array index, zero-based.$.book[0]
[-n]Negative index, counted from the end.$.book[-1]
[a,b]Union of several indices or names.$.book[0,2]
[start:end:step]Slice, end-exclusive. Any part may be omitted.$.book[1:4], $.book[::2]
[?(expr)]Filter — keep elements where expr is true.$.book[?(@.price < 10)]
@Inside a filter, the element being tested.[?(@.active == true)]
.lengthLength of an array or string.$.book.length

Writing filters

Filters are where JSONPath earns its keep, and where most people get stuck. The expression inside [?(...)] is evaluated once per element, with @ bound to that element.

OperatorNotesExample
== !=Compares primitives directly; objects and arrays are compared by their JSON form.[?(@.status == 'active')]
< <= > >=Only compares number-to-number and string-to-string. Mismatched types are never equal and never ordered, rather than coercing.[?(@.price >= 10)]
=~Regex match against a string, with a JavaScript regex literal on the right.[?(@.email =~ /@example\.com$/)]
&& || !Boolean logic, with () for grouping.[?(@.a > 1 && @.b != null)]
bare @.keyExistence test — true when the key is present and not undefined.[?(@.isbn)]

Things that surprise people

Recursive descent is greedy and unordered by depth. $..price returns every price anywhere in the document — nested three levels down, inside arrays, all of it. Results come back in document order, not shallowest-first, so if you only want top-level prices, say so explicitly with $.store.*.price.

A filter on a missing key is false, not an error. [?(@.price < 10)] silently skips elements with no price at all. That is usually what you want, but it means a typo in the key name returns zero matches rather than complaining — which is why this tool always shows the match count.

Slices are end-exclusive. [0:2] gives you elements 0 and 1, matching Python. [1:] drops the first element; [:-1] drops the last.

JSONPath is not standardised in the way people assume. The original 2007 article by Stefan Gössner is the common ancestor, but every implementation diverged. RFC 9535 (February 2024) finally specified it, and real-world tools are still catching up — so an expression that works in one library can behave differently in another, especially around filters, unions and how the root is handled. When an expression works here but not in your Java or Python library, that difference is usually the reason, not a bug in either.

Type coercion is deliberately absent. [?(@.count > '5')] returns nothing here rather than comparing a number to a string. Implementations that coerce produce results that look right until the day your data has "10" in it and sorts before "9".

How this tool works

The expression is parsed into a list of steps and evaluated against the document one step at a time, carrying the concrete path of every intermediate node. That is why each result shows its own path, such as $.store.book[2].title — you can copy that path straight into your own code to reach the same value. The parser and evaluator are about 500 lines of plain JavaScript in jsonpath.js, with no dependencies, and they run in your browser tab. Nothing you paste here is uploaded anywhere, which makes it safe to use with a production API response you would not paste into a remote service.

Need to tidy the JSON first? The JSON formatter and validator will pretty-print it and pin down any syntax error. For a deeper walkthrough, see the JSONPath cheatsheet.