What is JSONPath query? A complete beginner’s guide
If you have ever worked with APIs or tested web services, you have almost certainly dealt with JSON responses. They come back packed with data like nested objects, arrays, key-value pairs and finding the specific value you need can feel like searching for a needle in a haystack. That is exactly the problem JSONPath was built to solve.
Whether you are writing API tests, building a data pipeline, or just trying to pull a specific field out of a response, a JSONPath query gives you a clean and readable way to do it. This guide walks you through everything you need to know.
Introduction to JSONPath
JSON (JavaScript Object Notation) has become the standard data format for REST APIs. It is lightweight, human-readable, and easy to parse. But once a JSON response starts growing with multiple levels of nesting and arrays of objects, manually traversing it becomes tedious and error-prone.
JSONPath was introduced by Stefan Goessner in 2007 as a query language for JSON, inspired directly by XPath, which does the same job for XML. Just as XPath lets you navigate and extract data from an XML document using a path expression, JSONPath lets you do the same with JSON. Think of it as a way to write directions to any piece of data inside a JSON structure.
If you have ever used XPath for XML parsing or testing, JSONPath will feel immediately familiar. If you have not, do not worry, the syntax is straightforward and takes only a short while to get comfortable with.
What is a JSONPath query?
A JSONPath query is an expression that describes a path through a JSON document to locate one or more values. It starts at the root of the document and navigates through nodes like objects and arrays, using a specific set of operators and syntax rules.
Here is a simple JSON example to work with throughout this article:
json
{
“store”: {
“name”: “BookWorld”,
“books”: [
{ “title”: “The Alchemist”, “author”: “Paulo Coelho”, “price”: 9.99 },
{ “title”: “1984”, “author”: “George Orwell”, “price”: 7.49 },
{ “title”: “Sapiens”, “author”: “Yuval Noah Harari”, “price”: 12.00 }
]
}
}
A basic JSONPath query to get the name of the store would look like this:
$.store.name
That returns: “BookWorld”
Simple, clean, and immediately readable. The $ represents the root of the JSON document, and each dot followed by a key navigates one level deeper.
JSONPath syntax and operators
Before diving into more complex query expressions for JSON, it helps to understand the core building blocks of JSONPath syntax.
| Operator | Description |
| $ | The root element of the document |
| . | Child operator (dot notation) |
| .. | Recursive descent – searches all levels |
| * | Wildcard – matches all elements |
| [] | Subscript operator for arrays or child access |
| [n] | Access the nth element of an array (zero-indexed) |
| [start:end] | Array slice |
| [?()] | Filter expression |
| @ | The current node being evaluated (used in filters) |
These operators combine to form powerful query expressions for JSON that can navigate deeply nested structures with very little code.
How to use JSON path: Common patterns with examples
Accessing a specific field
To extract all book titles from our example:
$.store.books[*].title
Result: [“The Alchemist”, “1984”, “Sapiens”]
The [*] wildcard matches every element in the books array, and .title pulls the title from each one.
Accessing a specific array element
To get just the first book:
$.store.books[0]
This returns the entire first book object. JSONPath arrays are zero-indexed, so [0] gives you the first item, [1] the second, and so on.
Using recursive descent
The .. operator is one of the most powerful parts of JSONPath. It searches all levels of the JSON tree for a matching key, no matter how deeply nested it is.
$..author
This returns every author value found anywhere in the document, regardless of nesting depth.
Result: [“Paulo Coelho”, “George Orwell”, “Yuval Noah Harari”]
Filtering with expressions
This is where JSONPath gets really useful. Filter expressions let you select elements conditionally. To extract data from JSON where the book price is less than 10:
$.store.books[?(@.price < 10)]
The ?() is the filter operator, and @ refers to the current element being evaluated. This query returns all book objects where the price is below 10 — “The Alchemist” and “1984” in our example.
You can also filter by string values:
$.store.books[?(@.author == “George Orwell”)]
This returns only the book object written by George Orwell.
JSON path explained: The difference between dot and bracket notation
JSONPath supports two ways to navigate child elements: dot notation and bracket notation.
Dot notation is the more readable of the two:
$.store.books[0].title
Bracket notation wraps keys in quotes inside square brackets:
$[‘store’][‘books’][0][‘title’]
Both return the same result. Dot notation is generally preferred for clean, readable queries, but bracket notation becomes necessary when a key contains spaces, special characters, or starts with a number.
Where is JSONPath actually used?
JSONPath is not just a theoretical concept; it shows up in a wide range of practical tools and workflows.
API testing frameworks like Rest Assured (for Java) use JSONPath heavily to assert values in API responses. Instead of parsing an entire response object, testers write a single JSONPath query to extract and validate the field they care about.
HTTPBot, for example, supports JSONPath queries directly in its request and test configuration. This lets you write clean, readable assertions against any part of an API response without writing parsing code.
Data processing tools like jq, Jsonata, and many ETL pipelines use JSONPath-style querying to transform or filter large datasets.
Configuration and scripting tools including AWS Step Functions, Kubernetes, and several CI/CD platforms use JSONPath expressions to reference fields in structured data.
Common mistakes to avoid
A few things trip people up when first working with JSONPath:
Forgetting zero-based indexing – Arrays in JSONPath start at index 0, not 1. books[1] gives you the second book, not the first.
Using the wrong root symbol – Every JSONPath expression must start with $. Leaving it out will cause the query to fail or return unexpected results.
Confusing . and .. – A single dot moves one level down. Double dot performs a recursive search through the entire tree. Using .. when you only need . is a performance hit on large documents and can return more results than intended.
Misquoting string values in filters – String comparisons in filter expressions use == and require the value to be in double quotes: [?(@.status == “active”)].
Wrapping up
JSONPath is one of those tools that feels almost obvious once you start using it, you wonder how you managed without it. Whether you are extracting data from JSON API responses, writing test assertions, or processing structured data at scale, a well-written JSONPath query cuts through the noise and gets you exactly what you need in one clean expression.
The key is to get comfortable with the core operators, practice with real JSON structures, and gradually work your way up to filter expressions and recursive descent. Once those click, you will find yourself reaching for JSONPath instinctively any time you need to navigate a JSON document.
If you are working with APIs and want to write sharper, more maintainable tests and scripts, JSONPath is absolutely worth adding to your toolkit.
