JSONPath cheat sheet: syntax and examples

Every common JSONPath expression explained against one sample document, from simple property access to slices and filters, with notes on how implementations differ.

What JSONPath is for

JSONPath is a query language for picking values out of a JSON document. Instead of writing loops and null checks, you describe the path to the data and get back every value that matches. It was proposed by Stefan Goessner in 2007, spread through many slightly different libraries, and was standardized as RFC 9535 in 2024.

You will meet JSONPath in API testing tools, kubectl output formatting, AWS Step Functions, log processors, and integration platforms. Because those tools do not all support the same features, the most reliable habit is to test an expression against real sample data before relying on it.

The sample document

Every example on this page runs against this small store catalog. Paste it into a JSONPath tester and follow along.

{
  "store": {
    "name": "City Books",
    "books": [
      { "title": "Clean Code", "author": "Robert Martin", "price": 32, "tags": ["programming"] },
      { "title": "Dune", "author": "Frank Herbert", "price": 9, "tags": ["fiction", "classic"] },
      { "title": "Sapiens", "author": "Yuval Noah Harari", "price": 18, "tags": ["history"] },
      { "title": "Refactoring", "author": "Martin Fowler", "price": 41, "tags": ["programming"] }
    ],
    "address": { "city": "Pune", "country": "India" }
  }
}

The basics: root, children, and arrays

Every expression starts at $, the root of the document. From there you step into children with dot notation or bracket notation, and into arrays with zero-based indexes.

ExpressionResultMeaning
$.store.name"City Books"Dot notation for a child member
$['store']['name']"City Books"Bracket notation, needed for keys with spaces or symbols
$.store.books[0].title"Clean Code"First element of an array
$.store.address.city"Pune"Nested objects

Use bracket notation whenever a key contains spaces, hyphens, dots, or starts with a digit, for example $['order-id'] or $['2024']. Dot notation only works for keys that look like simple identifiers.

Wildcards and projections

The wildcard * selects every member of an object or every element of an array. Combined with a following path it acts as a projection: it collects the same field from every element.

ExpressionResult
$.store.books[*].title["Clean Code", "Dune", "Sapiens", "Refactoring"]
$.store.books[*].price[32, 9, 18, 41]
$.store.address.*["Pune", "India"]
$.store.books[*].tags[0]["programming", "fiction", "history", "programming"]

Projections are the workhorse of everyday JSONPath. Pulling every id from an API response, every email from a user list, or every status from a set of jobs is a single expression.

Recursive descent

Two dots, .., search every level of the document. $..price finds every price field no matter how deeply it is nested, and $..tags finds every tags array.

ExpressionResult
$..author["Robert Martin", "Frank Herbert", "Yuval Noah Harari", "Martin Fowler"]
$..city["Pune"]

Recursive descent is ideal for exploring an unfamiliar document, but it can return more than you expect when the same key appears in unrelated places. In production configuration, prefer an explicit path so that unrelated changes elsewhere in the document cannot change the result.

Array slices and negative indexes

Slices use the Python-style [start:end:step] syntax, where end is exclusive. Negative indexes count from the end of the array.

ExpressionResult
$.store.books[0:2].title["Clean Code", "Dune"]
$.store.books[-1].title"Refactoring"
$.store.books[-2:].title["Sapiens", "Refactoring"]
$.store.books[::2].title["Clean Code", "Sapiens"]

Filter expressions

Filters select array elements that match a condition. Inside the filter, @ refers to the element being tested. Classic implementations write filters as [?(...)]; RFC 9535 also accepts [?...] without the parentheses.

ExpressionResult
$.store.books[?(@.price < 20)].title["Dune", "Sapiens"]
$.store.books[?(@.author == 'Martin Fowler')].price[41]
$.store.books[?(@.price > 10 && @.price < 40)].title["Clean Code", "Sapiens"]

Filter support varies more than any other feature. Comparison operators, existence checks such as [?(@.isbn)], regular expressions, and functions like length() are implemented differently, or not at all, across libraries. Some tools also disable filters entirely because older implementations evaluated them as code.

JSONPath in real tools

Many tools embed JSONPath with small twists, so it pays to recognize the variations. Kubernetes kubectl uses a JSONPath template syntax: expressions sit inside curly braces and usually omit the leading $. To list the names of all pods, for example:

kubectl get pods -o jsonpath='{.items[*].metadata.name}'

AWS Step Functions uses paths such as $.detail.orderId to select parts of the state passed between steps, and many API testing and monitoring tools let you extract a value from a response with a JSONPath expression before asserting on it. In each case, the core syntax from this page carries over; what changes is support for advanced features such as filters and functions, so check the documentation of the tool you are using.

What the UtiliStudio JSONPath Tester supports

The JSONPath Tester uses a safe, declarative evaluator that never executes code. It supports the core syntax that covers most everyday lookups, and deliberately rejects filters and script expressions.

FeatureExampleSupported in the tester
Root and dot notation$.store.nameYes
Bracket notation$['store']['name']Yes
Array index$.store.books[0]Yes
Wildcards and projections$.store.books[*].titleYes
Array length$.store.books.lengthYes (extension, not part of RFC 9535)
Recursive descent$..priceNot yet
Slices and negative indexes$.store.books[-1]Not yet
Filters[?(@.price < 20)]No, by design

If your production tool supports filters, use the tester to confirm the path up to the array, then add the filter in your target tool and check the result there.

Tips for writing reliable expressions

  • Build incrementally. Start with $, add one step at a time, and check the result after each step.
  • Expect a list. JSONPath returns every match, so results are a list even when there is one value, and an empty list when nothing matches.
  • Check case and spelling first. Most empty results come from a typo in a key, the wrong letter case, or treating an object as an array.
  • Know your flavor. Test with the same implementation your production tool uses, especially for filters.
  • Consider JSON Pointer for single values. A pointer such as /store/books/0/title addresses exactly one location and is what JSON Schema errors and JSON Patch use.
Try it: JSONPath TesterEvaluate and test JSONPath expressions against complex JSON structures in real time.
Open JSONPath Tester