How to use the JSONPath Tester
- Paste or drop your JSON document into the data pane.
- Type a JSONPath expression starting with $ (the root).
- Read the matches: each result shows the value and its exact path, e.g. $.store.book[0].title.
- Refine with filters such as [?(@.price < 10)] and copy the expression or the result array.
Worked example
Titles of books cheaper than 10
JSON
{"store":{"book":[{"title":"Dune","price":9.99},{"title":"Emma","price":14.5},{"title":"Ulysses","price":7.25}]}}Expression
$.store.book[?(@.price < 10)].title
Result
[ "Dune", "Ulysses" ]
The filter keeps array elements whose price is below 10 (indexes 0 and 2), then .title selects one field from each. Results are always a list, even for a single match.
JSONPath syntax cheat sheet
The syntax this tester supports. Queries that start with $ are JSONPath; queries that start with . are treated as jq.
| Syntax | Meaning | Example |
|---|---|---|
| $ | Root of the document | $ |
| .name or ['name'] | Child member by name; use brackets for keys with spaces or dots | $['first name'] |
| [n] | Array element by index; negative counts from the end | $.items[-1] |
| [start:end:step] | Array slice, end exclusive | $.items[0:2] |
| [*] or .* | All children of an object or array | $.users[*].email |
| .. | Descendants at any depth | $..id |
| [?( … )] | Filter; @ is the current element. Operators: == != < <= > >= =~ && || ! | $.users[?(@.age >= 18)] |
| ['a','b'] or [0,2] | Union of several names or indexes | $.user['id','name'] |
| .length() | Length of an array, object or string | $.items.length() |
Filters that trip people up
A filter applies to the children of the node before the bracket, not to the node itself. $.store.book[?(@.price < 10)] tests each book; $.store[?(@.price < 10)] tests the values inside store, which is rarely what you want.
Comparing a missing member is not an error: elements without a price simply do not match. Use an existence test such as [?(@.price)] to keep only elements that have the field. String comparison needs quotes, e.g. [?(@.status == 'active')]. For pattern matching use =~ with a regular expression: [?(@.email =~ /@example\.com$/i)].
Implementation differences
JSONPath libraries differ. This tester supports .length() and =~ regex matching, which many older Java and JavaScript libraries also accept, but it does not implement the RFC 9535 functions count(), match(), search() or value(). If an expression works here but not in your code (or the other way round), check which dialect your library implements.
JSONPath Tester FAQ
What is the difference between JSONPath and jq?
JSONPath only selects values from a document. jq is a full transformation language that can also reshape, compute and build new JSON. Use JSONPath for config files, API assertions and tools that expect it; use jq in shell pipelines.
Why does my JSONPath return an empty array?
The most common causes are a wrong case in a key name, a missing [*] before a field on an array, or a filter placed on an object instead of an array. Remove the last segment and add it back to see where matches disappear.
How do I select a key that contains a dot or space?
Use bracket notation with quotes: $['user.name'] or $['first name']. Dot notation only works for simple identifier-like keys.
How do I get the last element of an array in JSONPath?
Use a negative index, $.items[-1], or a slice, $.items[-1:]. The index returns the value; the slice returns a one-element list.
Is JSONPath standardized?
Yes. RFC 9535 (February 2024) defines the syntax and semantics. Libraries still vary; this tester covers the common core (names, indexes, slices, wildcards, .., unions, [?( … )] filters, .length() and =~ regex) but not the RFC's count(), match(), search() or value() functions.
Does the recursive descent operator .. include the root?
$..* returns every descendant but not the root itself. $..price returns every member named price at any depth.

