JSONPath evaluator
The path, your document, and what it actually selects.
Examples temporarily replace the input and settings. You can restore your previous work.
Paste or type above to see the result here.
Your files stay on your device
This tool runs entirely in your browser. What you paste is processed on your device and is never sent to a server, so it is safe to use with tokens, keys and unpublished text.
Example
Example: emails, prices and big orders out of a small shop’s order export
A bookshop’s orders, exported as JSON: three orders, each with a customer (name and email), a country, a total and a list of items with sku, title, qty and price. Names and addresses are made up. Paste it once, then try one path after another, with Show the result as: One match per line.
- $.orders[*].customer.email → 3 matches: anna@example.com, ben@example.com, cara@example.com, ready to paste into a mail-out list.
- $.orders[?(@.country == "GB")].id → 1001 and 1003. Single or double quotes around GB both work.
- $.orders[?(@.total > 20)].customer.name → Ben Jones, the only order over 20.
- $..price → 18.99, 12.75, 16, 2.5: every price at any depth. Numbers come back as numbers, so 16.00 shows as 16.
- ?(@.total > 5 && @.country == "GB") gives Nothing matched: a filter takes one comparison. Run the GB filter as JSON, paste the result as the document, and $[?(@.total > 10)].id gives 1001.
| Path | Matches | Result |
|---|---|---|
| $.orders[0:2].id | 2 | 1001, 1002 |
| $.orders[-1:] | 1 | the whole last order, 1003 |
| $.orders[?(@.gift)].id | 1 | 1003, the only order with "gift": true |
| $..items[?(@.qty > 1)].title | 2 | Tide Tables, Gift card |
| $..items[?(@.sku =~ /^BK/)].sku | 2 | BK-2201, BK-1043 |
| $.order[*].id | 0 | Nothing matched. — orders was misspelt |
| $.orders[(@.length-1)] | — | refused as a script expression, with the list of what the page understands |
Each answer shows its count, so a path that should find three things and finds two stands out at once. Nothing leaves the browser, which matters when the export holds customers’ email addresses.
How it works
- Paste the JSON.
- Type the path: $.users[*].email, $..price, $.items[?(@.qty > 2)].name.
- Read what comes back, and the count above it.
- Switch to one match per line when you want a list to paste elsewhere.
Frequently asked questions
- Which dialect is this?
- The subset every implementation agrees on. JSONPath had no specification at all until RFC 9535 in 2024, by which time each library had its own dialect, so anything exotic works in one place and not another. This does names, indexes, slices, wildcards, recursive descent and comparison filters, and says so when you reach past that.
- Does it run script expressions?
- No, and deliberately. Some implementations evaluate $.a[(@.length-1)] by handing it to the language's own evaluator. Doing that with a string somebody pasted is indefensible, so those are refused with an explanation rather than run.
- What can a filter compare?
- == != > >= < <= and =~ for a regular expression, against a field of each item. @.qty > 2, @.name == "ada", @.sku =~ /^AB/, or just @.deleted to test that something is there at all.
- Why did my path match nothing?
- Usually a level too few or too many. Try the path one step at a time — $, then $.store, then $.store.book — and watch where the matches stop.
- Can a filter combine two conditions with && or ||?
- No — one comparison per filter. A filter written with && or || matches nothing rather than being refused, so do it in two passes: run the first filter with the result shown as JSON, paste that result as the document, and run the second filter on it as $[?(…)].
- Why does one match come back without square brackets?
- With JSON output, a single match is shown as the value itself — $.orders[1].total gives 41.5 — and several matches as a list in [ ]. One match per line never adds brackets, so the result pastes straight into a spreadsheet or a list.
- Is anything sent to a server?
- No. It runs in your browser, so what you paste stays on your computer.