Large JSON documents contain far more than you need at any given moment. An API response may hold hundreds of records, each with dozens of fields, when you only want the titles of the cheap items, or the email addresses of the active users, or the one nested value buried four levels down. Reading the whole document to find those values is slow, and writing code to extract them before you know the query is right is slower still. JSONPath is a small query language for this exact job: an expression that describes a path through a document, returning just the values that match.
The JSONPath Tester lets you try those expressions against real data in your browser. You paste in a document and a query, and it shows you what the query returns. The point of testing interactively is that JSONPath fails quietly: a query with a wrong field name or a misplaced bracket does not raise an error, it returns an empty result, and an empty result looks exactly like a document that genuinely contains no matches. Testing against data you understand is how you tell those two cases apart.
How the tool works
A JSONPath expression starts at the root of the document, written as $, and then navigates. A dot followed by a name selects a field: $.store.name gives the store's name. Brackets select an array element by position: $.store.book[0] gives the first book. A wildcard, *, selects all values at a level: $.store.book[*].title gives every book's title. A recursive descent, .., searches at any depth: $..title finds every title anywhere in the document, which is useful when you are not sure how deep a field is nested.
Filters are where JSONPath earns its keep. Inside brackets, a filter expression such as [?(@.price < 10)] keeps only the array items whose price is below 10, where @ refers to the item being tested. You can combine conditions, compare strings, and test for the existence of a field. Filters turn a path expression into a question: not "give me all the books" but "give me the books that cost less than ten". The tester evaluates your expression against the document you pasted and shows the matching values, so you can refine the filter until the result matches your intent.
The tester runs in your browser, so the document stays on your device. That matters when the JSON contains real records — user details, order data, internal identifiers — that you want to query without uploading. It also makes the loop fast: change one character in the query, see the result change immediately, and keep adjusting until the result is exactly right.
A worked example
Take this small bookshop document:
{
"store": {
"book": [
{ "title": "A Pocket Guide to Birds", "price": 8.99 },
{ "title": "The Long History of Maps", "price": 12.99 },
{ "title": "Cooking for One", "price": 9.50 }
]
}
}
Start with the simplest query, $.store.book[*].title. It returns all three titles, because the wildcard selects every book and .title picks each title. Now narrow it with a filter: $.store.book[?(@.price < 10)].title. Check each book against the condition: 8.99 is below 10, so the first book matches; 12.99 is not below 10, so the second does not; 9.50 is below 10, so the third matches. The query therefore returns exactly two titles: "A Pocket Guide to Birds" and "Cooking for One". Count them — two, not three — and you have verified the filter by hand.
Try a variation to see how a small change alters the result. Change the comparison to <= 9.50 and the result is still two titles, because 9.50 is equal to the boundary and the second book is still above it. Change it to < 9 and only the first book matches, because 9.50 is no longer below the threshold. Each of these results is checkable by hand against the three prices, and that hand-checking is the habit that makes query testing reliable: never accept a result you cannot explain from the data.
A common next step is to combine conditions. The query $.store.book[?(@.price < 10 && @.title != "Cooking for One")].title returns only "A Pocket Guide to Birds", because the third book is excluded by the second condition even though it passes the first. When a combined filter returns nothing, test each condition separately to find which one is excluding everything — it is usually a misspelled field name or a comparison against the wrong type.
Common mistakes
The most common mistake is a field name that does not match the document. JSONPath is case-sensitive, and $.store.Book will not match a field named book. Because a failed match returns an empty result rather than an error, a typo looks identical to a genuinely empty result. When a query returns nothing, first test a simpler query — $.store or $.store.book — and confirm that each step of the path exists before adding filters.
The second mistake is forgetting that array indexes start at zero. book[1] is the second book, not the first, and book[3] in a three-book array returns nothing because the valid indexes are 0, 1, and 2. Off-by-one errors in indexes are the JSONPath equivalent of the same error in programming, and they are just as common.
The third mistake is comparing values of different types. A filter such as @.price < "10" compares a number with a string, and depending on the implementation it may match nothing or behave unexpectedly. Numbers in JSON are not quoted; strings are. If a filter behaves strangely, check whether the value in the document and the value in your query are the same type.
The fourth mistake is overusing recursive descent. $..title is convenient, but it searches the entire document, and in a large document it may return titles from unrelated sections that happen to share a field name. Prefer an explicit path when you know the structure, and reserve recursive descent for exploration, when you are still learning where a field lives.
Honest limitations
A JSONPath tester evaluates queries; it does not fix your data, explain your API, or guarantee that a query will work in every implementation. JSONPath has no single universally implemented standard: different libraries support different features, and a filter or function that works in one tester may not work in the code that will run the query in production. Always test the final query with the library you will actually use. The tester also cannot help with documents that are invalid JSON — a syntax error in the document must be fixed first — and it cannot query data that is not JSON at all, such as XML or YAML, without conversion. Finally, a query that returns the right result on a small sample may behave differently on the full document if the full document contains field-name collisions or mixed types that the sample lacked. Test on representative data, not just a tidy example.
Closing
JSONPath is a precise instrument, and precision is only useful when it is tested. Build the query one step at a time, verify each result by hand against data you understand, and test filters separately before combining them. To browse a whole document as a table rather than querying it, use the JSON Table Explorer, and for formatting and validating the document itself, use JSON Studio. For the wider technique in full, see How to Query JSON with JSONPath to Pull Out Exactly the Fields You Need.