JSONPath Evaluator
Query JSON the way you would in code.
Write a JSONPath expression, run it, and see every match with its resolved path and value. Click a node in the tree to have its path written for you, then generalise it into a query.
Input JSON
No values matched $.projects[*].name.
What JSONPath is for
JSONPath is a query language for JSON, in roughly the way XPath is one for XML. You write an expression describing where a value lives, and you get back every value that matches — one, none, or several hundred.
It is worth learning because it turns up everywhere once you notice it: Kubernetes kubectl -o jsonpath, CI pipeline conditions, API gateway response mapping, log processors, Postman assertions and countless integration tools. The same expression you test here usually pastes straight into one of them.
The syntax, with real results
Every result below is what this page returns for a document with three projects under $.store.projects, two of them active.
Bracket notation is always available and is what you need for keys that are not identifiers: $['shipping-address'].city. The viewer writes paths in that form automatically when it has to.
Filters
Filters are where JSONPath stops being a lookup and starts being a query. ?() takes an expression evaluated against each item, with @ standing for the item.
$.store.projects[?(@.status=="active")].name ["api", "cli"]
$.store.projects[?(@.stars > 10)].name ["api", "cli"]
$.store.projects[?(@.owner)].name ["api", "web"]
$.store.projects[?(@.name.match(/^a/))] the "api" object
$..[?(@.email)] every object anywhere with an emailThe third form — a bare field name — tests for existence, which is the fastest way to find the records that are missing something. The fourth shows that string methods work inside a filter; .match() with a regular expression is the one worth remembering.
What a match actually gives you
Each result carries four things, not just the value:
{
"path": "$['store']['projects'][1]['name']",
"pointer": "/store/projects/1/name",
"parentProperty": "name",
"value": "web"
}The path is normalised to bracket form — it will not look like the expression you typed, and that is deliberate: it is unambiguous and always valid. The pointer is an RFC 6901 JSON Pointer, which is what JSON Patch, OpenAPI and many schema validators expect. Getting both means you can query in one notation and act in the other.
From a tree click to a query
The practical workflow is not to write expressions from memory. It is to find one example of what you want, copy its path, and widen it.
- Find any single matching value in the tree view and right-click → Copy JSON Path.
- Paste it here. You now have an expression that returns exactly one value, and you know it is correct.
- Replace a concrete index with
*to get every sibling:$.users[3].emailbecomes$.users[*].email. - Replace the leading path with
..if the field appears at several depths:$..email. - Add a filter to narrow it back down:
$.users[?(@.active)].email.
Each step is verifiable against the real document, so you never have to guess whether an expression works — you can see how many matches it returned.
Filters cannot run code
Historically, JSONPath filter expressions were evaluated with eval, which meant a query was arbitrary JavaScript. This page runs a restricted evaluator instead: expressions can read the data and compare it, and nothing else. All of the following are rejected outright rather than executed.
A note on dialects
JSONPath went unstandardised for two decades, so implementations diverge. It was finally specified as RFC 9535 in 2024, and most existing tools — including the widely used jsonpath-plus, which powers this page — predate it and carry extensions.
$..namerecursive descent,[*], slices and filters are universal. Use these freely..length, the parent operator^and the property-name operator~are extensions. They work here and will not work everywhere.- Regular expressions inside filters vary by implementation.
- Behaviour on no match differs: some implementations return an empty list, others an error.
If the expression is destined for kubectl or another specific tool, test it there before relying on it. If it is for your own code, pick a library and stay with it. For everything else, the universal subset is enough surprisingly often.
Frequently asked questions
Which JSONPath dialect is used?
jsonpath-plus, in its restricted evaluation mode. It supports the common syntax plus extensions such as ^, ~ and .length. JSONPath was standardised as RFC 9535 only in 2024, so expressions using extensions may not port to other tools.How do I get every value of one field?
$.users[*].email — or recursive descent if you do not: $..email finds every email at any depth.Can I filter by a value?
$.users[?(@.active==true)] compares, $.users[?(@.age > 30)] works on numbers, and $.users[?(@.email)] tests that a field simply exists.Why does the returned path look different from my expression?
$['users'][0]['email']. It is unambiguous and always valid, including for keys containing dots or hyphens. Each result also carries an RFC 6901 JSON Pointer.Can a JSONPath expression run arbitrary code?
Are queries run on a server?
Why does my query return nothing?
Related JSON tools
- JSON ViewerExplore JSON as a collapsible tree with search and copyable paths.
- JSON AnalyzerProfile structure and surface data-quality problems.
- JSON to CSVTurn arrays of records into a spreadsheet-ready CSV.
- JSON ValidatorCheck syntax with precise line, column and cause.
- JSON FormatterPretty-print messy JSON with your choice of indentation.