What Is JSONPath? Querying JSON Explained
You have a 4,000-line API response and you need one thing out of it: the ID of the third order for a customer buried four levels deep. You could write a loop, or a chain of response.data.customers[2].orders... that breaks the moment the shape shifts. Or you could write $.customers[2].orders[2].id and be done. That expression is JSONPath, and this is the whole language.
JSONPath is a query language for JSON โ a short string that describes which values to pull out of a document. If you've ever used XPath to select nodes from XML, it's the same idea ported to JSON. And if you haven't, there's an analogy you already know cold: a file path.
The mental model: a path through folders
Think about how you point at a file: /Users/you/projects/report.pdf. You start at the root, then name each folder you descend into until you reach the thing you want. JSONPath is that exact motion applied to data. The root of a JSON document is $. Every expression starts there and walks inward.
Say you have {"user": {"name": "Ada", "roles": ["admin", "editor"]}}. Then:
$is the whole document.$.useris the user object.$.user.nameis"Ada".$.user.roles[0]is"admin".
Dot notation ($.user.name) and bracket notation ($['user']['name']) mean the same thing; you reach for brackets when a key has a space or a special character that dot notation can't express. If you want to see the tree you're navigating before you write the path, drop the document into the JSON Viewer and expand it visually; the nesting you click through is the nesting your path walks.
Arrays: indexes and slices
JSON arrays are ordered, so you address them by position, starting at zero. $.items[0] is the first element, $.items[2] the third. Negative indexes count from the end in most engines, so $.items[-1] is the last.
The move that saves the most code is the slice, borrowed from Python: $.items[0:3] returns the first three elements as a group. $.items[2:] gives everything from the third element on. One expression, a whole sub-range, no loop.
Where it stops being a lookup and starts being a query
Everything so far is addressing โ pointing at one known spot. The reason JSONPath earns the name 'query language' is three operators that match many things at once.
- Wildcard
*โ matches every element at a level.$.users[*].emailcollects the email of every user in the list, however many there are. - Recursive descent
..โ searches every depth.$..idfinds everyidproperty anywhere in the document, no matter how deeply it's buried. This is the one you'll reach for constantly against messy nested payloads. - Filters
[?(...)]โ keep only elements that pass a test.$.products[?(@.price < 10)]returns every product cheaper than ten, where@means 'the element currently being tested.' Combine them โ$..products[?(@.inStock)].nameโ and you're querying, not just looking up.
One honest caveat: the dialects
JSONPath grew as a de-facto standard, which means tools disagreed on the edges โ especially filter syntax and whether results come back as values or as paths. In 2024, RFC 9535 finally standardized it, but plenty of libraries predate that and still have quirks. The practical rule: whatever engine your code will use, test the expression there first. Guessing that your test runner's JSONPath matches your database's is how you ship a query that returns nothing.
This is exactly what a JSONPath Tester is for โ paste your real JSON, type an expression, and watch which values light up, adjusting until it selects precisely what you meant. When you just need the shape of an unfamiliar payload rather than specific values, the JSON Key Extractor lists every key at every depth, and the JSON Formatter makes the raw document readable enough to plan the path in the first place.
JSONPath vs JSON Pointer
One point of confusion worth clearing: JSONPath is not a JSON Pointer. A JSON Pointer (the /user/name syntax you see in JSON Schema errors and JSON Patch) addresses exactly one location, precisely and unambiguously. JSONPath is the broader query tool that can return many matches with wildcards and filters. Pointer when you know the single spot; JSONPath when you're selecting a set.
The one-line version
JSONPath is a file-path-style query language for JSON: start at $, walk in with dots and brackets, and reach for *, .., and filters when you need to match many values instead of one. It reads, never writes. Learn the five operators above and you can extract anything from any JSON document โ test the expression in the JSONPath Tester and let the results confirm you got it right. For the ground-level basics of the format itself, start with what JSON is.
Try the tools
Frequently Asked Questions
What is JSONPath used for?
Pulling specific values out of a JSON document without writing loops: extracting fields from an API response, configuring integrations and webhooks, writing test assertions, and querying config files. It's the JSON equivalent of XPath for XML.
What does the $ mean in JSONPath?
`$` is the root of the document โ every expression begins there. `$.name` means 'the name property at the top level.' Inside a filter expression, `@` refers to the current element being tested rather than the root.
What's the difference between JSONPath and a JSON Pointer?
A JSON Pointer (RFC 6901) addresses exactly one location with a slash path like `/user/name`. JSONPath is a richer query language with wildcards, slices, and filters that can match many values at once. A pointer is a single address; JSONPath is a query.
Does JSONPath have an official standard?
For years it was a de-facto spec with differences between tools, especially around filter syntax. RFC 9535 (published 2024) standardizes it, but many older libraries still vary โ so test your expression in the same engine you'll actually run it in.
How do I select every value of a key at any depth?
Use recursive descent: `$..price` finds every `price` property anywhere in the document, no matter how deeply nested. Add a wildcard like `$..*` to walk every value in the tree.
Lauren Prescott writes for CodeUtilityKit, where the team builds free, privacy-first developer tools that run entirely in your browser. Every guide is written and reviewed by developers who use these tools daily.