UseToolSuite UseToolSuite

JSON Path Finder

Click any value in your JSON to get its exact path, test an expression against your own data, or have an existing one explained segment by segment.

Quick:

JSONPath syntax quick reference

JSONPath uses dot notation and bracket notation to navigate JSON structures. The root element is $, child access uses $.store.book or $['store']['book']. Array indexing is zero-based: $.store.book[0] gets the first book. Wildcards (*) select all children: $.store.book[*].author extracts all authors. The recursive descent operator .. searches all levels: $..price finds every price field regardless of depth. Filter expressions like $.store.book[?(@.price < 10)] select elements matching a condition.

A JSONPath cheat sheet for real queries

Most day-to-day querying uses a small set of operators. Keep this table handy:

ExpressionReturns
$.store.book[0].titleFirst book’s title
$.store.book[*].authorEvery book’s author
$..authorAll author values, any depth
$.store.book[-1]Last book
$.store.book[0:2]First two books (end-exclusive)
$.store.book[?(@.price < 10)]Books cheaper than 10
$..*Every value in the document

The $ is always the root, @ refers to the current element inside a filter, and .. scans recursively at every depth.

Reading an expression you didn’t write

Most JSONPath tools assume you are composing a query. The harder job is the opposite one: a colleague’s config, a Jenkins step, or a Grafana panel contains $.items[?(@.status=='active')].meta.tags[-1] and you need to know what it selects before you change it. This tool will break an expression into its segments and describe each one, which is why the explain mode exists alongside the evaluator.

The reading order is strictly left to right, and each segment narrows or expands the set of nodes carried forward:

SegmentEffect on the set
$Start with one node: the whole document
.itemsReplace it with the value at items
[?(@.status=='active')]Keep only members where the test passes
.metaReplace each survivor with its meta value
.tagsReplace each with its tags value
[-1]Keep the last element of each

Two habits make this reliable. Evaluate prefixes — run $.items, then $.items[?(@.status=='active')], and watch where the count collapses; the segment that empties the result is the one that is wrong. And remember that the result is always a list of nodes, never a single value: $.items[0].name returns a one-element list, not a string, which is why so many pipelines end with an index or a [0] that looks redundant.

Why the same expression gives different answers in different tools

JSONPath spent twenty years as a blog post rather than a standard. Independent implementations diverged on genuinely ambiguous cases — how a slice with a negative step behaves, whether recursive descent visits the root itself, whether duplicate matches are collapsed, and whether an expression that matches nothing is an empty result or an error. Two libraries could both be defensible and still disagree about the same query.

RFC 9535 settled it in February 2024. If you are debugging a mismatch between a query that works locally and one that fails in production, check the two implementations’ RFC compliance before assuming your expression is wrong — a pre-RFC library and a compliant one can legitimately return different node lists for identical input. The RFC also defines a small function set (length(), count(), match(), search(), value()), so a filter using any of those requires a reasonably current implementation on both ends.

The two operators that cause the most confusion

Recursive descent (..) is powerful but blunt — $..author finds every author anywhere in the tree, which is exactly what you want until it returns far more than expected on a large document. Narrow it with a specific key, and prefer an explicit path ($.store.book[*].author) when you know the structure.

Filters (?()) trip people on syntax: the current element must be @ (not $), string comparisons need quotes (?(@.name == 'Jane')), and the operator is == not ===. Get those three right and filters become the most useful tool in the set.

JSONPath, JMESPath, or jq?

They solve overlapping problems with different trade-offs:

  • JSONPath — XPath-style, great for selecting values from API responses; now RFC 9535.
  • JMESPath — also query-focused, with a more consistent spec; used by AWS CLI’s --query.
  • jq — a full command-line language that can transform, reshape, and compute, not just select. Steeper to learn, far more powerful for editing.

If you only need to find values, JSONPath is the simplest. If you need to reshape JSON, that’s jq territory.

Debugging a query that returns nothing

An empty result almost always means a path mismatch, and the usual suspects are: case sensitivity ($.User ≠ $.user), a missing array index (a value inside an array needs [0] or [*]), or the wrong nesting level. Start broad with $.* to list the top-level keys, then walk down level by level. Everything runs locally in your browser, so you can iterate on sensitive API responses without anything leaving your device.

Last updated Built and maintained by Necmeddin Cunedioglu How tools are tested

How to Use This Tool

  1. 1

    Paste your JSON

    Drop in an API response, a config file, or anything else. It stays in your browser — nothing is uploaded.

  2. 2

    Find the path instead of guessing it

    Click "Find Path" to walk the document as a tree, then click the value you want. Its exact JSONPath drops into the expression box and runs immediately. Use the filter to jump straight to a key or a value in a large document.

  3. 3

    Or write the expression yourself

    Type a JSONPath such as $.store.book[?(@.price<20)], or start from one of the quick examples, and press Enter.

  4. 4

    Check what it actually selects

    Click "Explain" to read the expression back in plain English, so an inherited path from someone else's config is not a guessing game.

  5. 5

    Copy or share the result

    Copy the matched JSON, or use Share to produce a link that restores both the data and the expression.

How helpful was this tool?

Click to rate

Key Concepts

JSONPath

The query language this tool reads and writes: an expression such as $.store.book[0].title that selects one or more values out of a JSON document, the way XPath does for XML. Every expression starts at the root, $, and each following segment narrows the selection. The individual operators are covered by the entries below and by the JSONPath syntax quick reference further down this page.

Root Element ($)

The $ symbol represents the root of the JSON document in JSONPath expressions. Every valid JSONPath expression starts with $. For example, $.name accesses the "name" property at the top level of the JSON object. The root element can be an object ({}) or an array ([]), and all subsequent path navigation operates relative to this root.

Recursive Descent (..)

The double-dot operator (..) in JSONPath performs a deep scan of the entire JSON structure, searching for a specified key at all nesting levels. For example, $..author finds every property named "author" regardless of its depth in the document. This is extremely useful for extracting all occurrences of a field from deeply nested or irregular JSON structures, but can return large result sets on complex documents.

Filter Expression (?())

A JSONPath filter expression evaluates a condition against each element and returns only those that match. Written as ?(@.property operator value), where @ represents the current element being evaluated. For example, $.books[?(@.price < 20)] returns all book objects whose price property is less than 20. Comparison operators include ==, !=, <, >, <=, and >=.

Frequently Asked Questions

How do I find the JSONPath of a value without knowing the syntax?

Click "Find Path". The tool renders your JSON as a list of nodes, each one clickable — pick the value you can see and its exact JSONPath is written into the expression box and evaluated straight away. The filter box narrows a large document to the keys or values you type, and shows full paths so you can still tell where each match sits. That is the reverse of a normal JSONPath tester, which needs you to know the expression before you can find anything.

Can it tell me what an existing JSONPath expression does?

Yes — paste it in and click "Explain". The expression is read back as a sentence, so $.store.book[?(@.price<20)] becomes "Start at the root of the document, then take the store property, then take the book property, then keep only the items whose price is less than 20." It covers child access, array indices including negative ones, slices, wildcards, recursive descent and filter comparisons.

Can I paste the path this tool gives me straight into my code?

Yes — the expression box emits standard JSONPath, so it drops straight into Jayway JsonPath in Java, jsonpath-ng in Python, jsonpath-plus in JavaScript, or any client that accepts the syntax. Two things are worth checking before you commit it. Bracket notation is the safer form to copy when a key contains a space, a dash or a dot, because dot notation cannot address those keys. And libraries still differ at the edges of filter expressions, so run the expression here against real data first and confirm it selects exactly what you expect. The JSONPath syntax quick reference further down this page lists every operator this tool evaluates.

Does this tool support all JSONPath expressions?

This tool supports the most commonly used JSONPath operators: root ($), child (.), recursive descent (..), wildcard (*), array indices ([0]), array slices ([start:end]), and filter expressions (?()). It covers the vast majority of real-world use cases for querying REST API responses and configuration files.

Can I use this tool to query large JSON files?

Yes. All processing happens in your browser, so there are no server-imposed limits. Most modern browsers handle JSON files up to 5–10 MB without performance issues. For very large files (10MB+), the query may take a moment depending on your device.

What is the difference between JSONPath and jq?

JSONPath is a query language designed for JSON navigation in web applications and APIs, using syntax like $.store.book[*].author. jq is a command-line tool for Linux/macOS that provides more powerful transformation capabilities including pipe operators, conditionals, and output formatting. JSONPath is simpler to learn; jq is more powerful but has a steeper learning curve.

Why does the same JSONPath expression give different results in different tools?

JSONPath was a 2007 proposal, not a formal standard for most of its life, so implementations diverged — especially on edge cases like filter syntax, how the root is handled, whether results are deduplicated, and the behavior of recursive descent. The IETF only standardized it as RFC 9535 in 2024, and not every library conforms yet. Practical consequences: a filter that works in one library may need different quoting in another, and some support script expressions or extensions others don't. When portability matters, stick to the common core (root $, child ., recursive .., wildcard *, index [n], slice [a:b], filter ?()) and test against the specific engine your code will run.

Can JSONPath modify data, or only read it?

JSONPath is a read-only query language — it selects and extracts values from a JSON document but doesn't change them. Think of it like a SELECT, not an UPDATE: $.users[?(@.active)].email returns matching emails, but there's no JSONPath syntax to set or delete them. To modify JSON based on a path, you read the values with JSONPath, then write changes with your programming language (or use a different tool built for transformation, like jq, which has full editing and reshaping capabilities). This tool evaluates queries and shows you what matches, entirely in your browser.

Troubleshooting & Technical Tips

JSONPath returns empty result: No match found for expression

An empty result usually means the path does not exist in the JSON structure. Common causes: (1) Case sensitivity — JSON keys are case-sensitive, so $.User is different from $.user. (2) Missing array index — if a value is inside an array, you need [0] or [*] to access it. (3) Wrong nesting level — use this tool's tree view to visually inspect the JSON structure and find the correct path. Try $.* to see all top-level keys first.

Filter expression syntax error: Unexpected token in ?()

Filter expressions must follow the format ?(@.property operator value). Common mistakes: (1) Missing @ symbol — the current element must be referenced with @, not $. (2) String values must be quoted: ?(@.name == 'John'), not ?(@.name == John). (3) Comparison operators use == (not ===). Example: $.books[?(@.price < 20)] returns all books with price less than 20.

Recursive descent (..) returns too many results

The recursive descent operator (..) searches the entire JSON tree at all levels. If used without a specific key, it returns every value in the document. To narrow results, always follow .. with a specific property name: $..author finds all "author" values at any depth, while $..* returns literally every value. For better precision, use explicit paths where possible: $.store.book[*].author instead of $..author.

Array slice [start:end] behaves unexpectedly

JSONPath array slices follow Python-style conventions: [start:end] is inclusive of start and exclusive of end. So [0:3] returns elements at indices 0, 1, 2 (not 3). Negative indices count from the end: [-1] is the last element, [-2:] returns the last two elements. If you want a single element, use [0] (index) instead of [0:1] (slice). Use [:5] to get the first 5 elements.

Related Guides

Related Tools

Embed this tool on your site

Paste this snippet into any HTML page or blog post to embed a live, fully working copy of JSON Path Finder. Free for any use.