JSONPath & JMESPath Tester
Standard JSONPath and AWS-style JMESPath queries, evaluated live on your JSON.
Result
Document with the matches highlighted
Syntax cheat sheet
| Syntax | Meaning | Example |
|---|---|---|
$ | The root of the document (every query starts with it) | $ |
.name or ['name'] | A member of an object; brackets for any name, with ' or " | $.store['bicycle'] |
[0], [-1] | An array element by index; negative counts from the end | $.store.book[-1] |
[start:end:step] | A slice of an array (end not included); any part can be left out | $.store.book[::2] |
* or [*] | All members of an object or all elements of an array | $.store.* |
..name, ..*, ..[…] | Descendants: the step applied at every depth | $..price |
[a, b] | Several selectors at once; results are joined in order | $.store.book[0, -1] |
[?filter] | Elements (or member values) for which the filter is true; @ is the current one | $..book[[email protected] < 10] |
== != < <= > >= | Comparisons of values from singular queries, literals and functions | $..book[[email protected] >= 8.99] |
&& || ! ( ) | Combine and negate filter conditions | $..book[?!(@.price > 10)] |
@.name | An existence test: true when the query finds something | $..book[[email protected]] |
length(v) | Characters of a string, items of an array or members of an object | $..book[?length(@.title) > 15] |
count(q) | How many nodes a query selects | $..book[?count(@.*) == 5] |
match(s, 're') | The whole string matches an I-Regexp (RFC 9485) | $..book[?match(@.isbn, '0-.*')] |
search(s, 're') | Some part of the string matches the I-Regexp | $..book[?search(@.author, 'Mel')] |
value(q) | The value of a query that selects exactly one node | $..book[?value(@..price) > 20] |
| Syntax | Meaning | Example |
|---|---|---|
name, "quoted name" | A field of an object (null when missing); quote names with other characters | Reservations |
a.b | A field of a field (a subexpression) | State.Name |
[0], [-1] | An array element by index; negative counts from the end | Reservations[-1] |
[start:stop:step] | A slice, with Python rules | Reservations[::-1] |
[*] and .* | Projections over the elements of an array or the values of an object | Reservations[*].Instances |
[] | Flatten one level of nested lists (also a projection) | Reservations[].Instances[] |
[?expr] | A filter projection: keeps elements for which expr is true | Instances[?State.Name=='running'] |
| | A pipe: stops the projection and applies the right side to the whole result | Reservations[].Instances[] | [0] |
[a, b] and {x: a, y: b} | Multi-select lists and hashes: build new arrays and objects | {id: InstanceId, type: InstanceType} |
`json` and 'text' | Literals: JSON in backticks, raw strings in single quotes | Tags[?Key=='Name'] |
== != < <= > >= | Comparisons; < and > work on numbers (and, in the AWS CLI, strings) | CpuOptions.CoreCount > `1` |
&& || ! ( ) | Logic: && and || return one of their operands | a || `"default"` |
@ | The current node | length(@) |
&expr | An expression reference, for sort_by(), max_by(), min_by() and map() | sort_by(@, &InstanceType) |
functions | abs avg ceil contains ends_with floor join keys length map max max_by merge min min_by not_null reverse sort sort_by starts_with sum to_array to_number to_string type values | join(', ', Tags[].Key) |
About the JSONPath & JMESPath Tester
Paste a JSON document and type a query: the result updates as you type. JSONPath follows RFC 9535, the IETF standard — every match is listed with its normalized path ($['store']['book'][0]), marked in the document, and one click selects it in the editor. JMESPath follows jmespath.py, the implementation behind the AWS CLI's --query option, so you can build a query here and copy it straight into your shell.
Both languages are interpreted, never run as code, and both implementations pass every case of their official test suites: the JSONPath Compliance Test Suite and the JMESPath compliance tests. Numbers keep every digit, and the page works offline once loaded — nothing you paste leaves your device.
How to use it
- Choose JSONPath (RFC 9535) or JMESPath (AWS CLI).
- Paste your JSON, open or drop a
.jsonfile, or press Load sample (the RFC's bookstore for JSONPath, anaws ec2 describe-instances-style response for JMESPath). - Type an expression, or choose one from Examples. Errors show the position with a marker under the expression; Select in the expression highlights it.
- For JSONPath, read the Matches (normalized path and value; Show selects the value in the editor and outlines it in the highlighted document), or switch to Values (a JSON array) or Paths.
- For JMESPath, pick the JSON layout (4 spaces looks like the AWS CLI) and use Copy as --query to get the quoted argument for bash or zsh.
Examples
$..book[[email protected] < 10].title
["Sayings of the Century", "Moby Dick"]
$.store.bicycle.*
$['store']['bicycle']['color'] $['store']['bicycle']['price']
Normalized paths always use brackets, so they are unambiguous for any member name.
Reservations[].Instances[?State.Name=='running'].InstanceId[]
["i-0123456789abcdef0", "i-0123456789abcdef2"]
Reservations[].Instances[].{ID: InstanceId, Type: InstanceType}--query 'Reservations[].Instances[].{ID: InstanceId, Type: InstanceType}'Single quotes inside the expression are written as '\'' so that bash and zsh pass it through unchanged.
Common uses
- Working out a JSONPath for an API test, a Kubernetes or OpenAPI tool, or a database that implements RFC 9535.
- Building an
aws … --queryoraz … --queryexpression against a saved response before running it for real (the Azure CLI uses JMESPath too). - Finding where values sit in a large document: every JSONPath match comes with its exact path.
- Checking whether an expression written for another JSONPath library is standard RFC 9535.
JSONPath (RFC 9535) in short
A query starts with $, the whole document, followed by steps: .name or ['name'] for an object member, [0] or [-1] for an array element, [1:3] for a slice, * for every child and .. for every depth. [?…] keeps the children for which a filter is true; inside it @ is the child being tested: $..book[[email protected] < 10 && @.category == 'fiction']. Filters can test that something exists ([[email protected]]), compare values, and call five functions: length(), count(), match(), search() and value().
RFC 9535 is stricter than many older JSONPath libraries, and this tester reports their syntax as errors rather than guessing: script expressions such as [(@.length-1)] (write [-1]), =~ (use match() or search()), in, and .length as a property (use length() in a filter). Comparisons need singular queries — @.a, @['b'][0] — because a query such as @.tags[*] can select several values; use count() or value() for those.
Regular expressions in match() and search()
match() succeeds when the whole string matches the pattern, search() when part of it does. Patterns are I-Regexp (RFC 9485), a small subset that works the same everywhere: characters, ., […] classes, *, +, ?, {n,m}, |, groups and Unicode categories such as \p{Lu}. There is no \d, \w or \s (write [0-9]), no look-ahead and no back-references, and . does not match a line break. A pattern that is not valid I-Regexp makes the function false, as the standard says. Queries stop after 3 seconds, so a pattern that backtracks badly cannot freeze the page.
JMESPath as in the AWS CLI
Reservations[] flattens a list and [*] and .* project over lists and objects: the rest of the expression is applied to each item, and items that give null are dropped. A pipe | stops the projection. [?State.Name=='running'] filters, {id: InstanceId} and [a, b] build new objects and lists, 'text' is a string, and JSON literals go in backticks. A missing field gives null rather than an error.
This tester follows jmespath.py, the library the AWS CLI uses: < and > also compare strings, the 26 built-in functions (sort_by(), max_by(), join(), to_number()…) have the same type rules and error cases, and the numbers they compute are written as Python writes them — the average of 2 and 4 is 3.0.
JSONPath or JMESPath?
- JSONPath selects parts of a document and tells you where they are; it is an IETF standard, which makes it a good choice for configuration, tests and APIs that must behave the same in every language.
- JMESPath reshapes data: projections, multi-select lists and hashes, pipes and functions turn a large response into exactly the list or table you want, which is why the AWS and Azure command-line tools use it for
--query.
Limitations
- Only standard syntax is accepted: extensions of other JSONPath libraries (Jayway, JSONPath-Plus) and of the newer "JMESPath Community" edition (let expressions, arithmetic) are reported as errors.
- The document must be strict JSON; comments, trailing commas or single quotes are reported with their line and column.
- Matches are highlighted in documents up to 400 KB and listed up to 2,000; every match is counted, and Values, Copy and Download contain all of them — up to 20 million characters, beyond which the tester asks for a narrower query instead of running out of memory.
- A query that takes longer than 3 seconds is stopped.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
Is my JSON uploaded?
No. Parsing and every query run in your browser, in a background worker; nothing is sent anywhere, and the page works offline once loaded.
Why does $.store.book.length return nothing?
In RFC 9535, .length means a member called "length", and arrays have none. length() and count() are used inside filters — for example $..book[?length(@.title) > 15] — and the last element of an array is [-1]. The number of matches of any query is shown above its results.
Why is my comparison rejected as "not a singular query"?
A comparison needs one value on each side. @.price or @.tags[0] select at most one value, but @.tags[*] or @..price can select several, so RFC 9535 does not allow them in a comparison. Use count(@.tags[*]) > 0, or put a filter inside: $[[email protected][?@ == 'sale']].
How do I use the JMESPath expression with the AWS CLI?
Press Copy as --query and paste the result after your command, e.g. aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'. The quoting is for bash, zsh and other POSIX shells; PowerShell and the Windows command prompt quote differently.
Why does JMESPath give null instead of an error?
JMESPath returns null for anything that is missing — a field that does not exist, an index past the end, a filter on something that is not a list. Errors are reserved for invalid syntax and for functions called with the wrong types, such as abs('x').