Skip to content

JSONPath: A Complete Guide to Querying JSON Data

JSONPath is a query language for JSON, similar to what XPath does for XML. It lets you navigate through a JSON document and extract specific values using a concise expression syntax. Whether you are debugging API responses, writing tests, configuring data pipelines or building search features, JSONPath saves you from writing custom traversal code. In this guide, we will cover the full JSONPath syntax, walk through practical examples and show you how to use it in different environments.

JSONPath Basics

Every JSONPath expression starts with $, which represents the root of the JSON document. From there, you use dot notation or bracket notation to navigate deeper:

// Sample JSON

{

"store": {

"name": "Tech Books",

"books": [

{ "title": "Clean Code", "price": 35 },

{ "title": "Refactoring", "price": 45 },

{ "title": "Design Patterns", "price": 50 }

]

}

}

$.store.name → "Tech Books"

$.store.books[0].title → "Clean Code"

$.store.books[*].title → ["Clean Code", "Refactoring", "Design Patterns"]

JSONPath Syntax Reference

Here is a complete reference of JSONPath operators and their meanings:

$Root object/element@Current object/element (used in filters).keyChild operator (dot notation)['key']Child operator (bracket notation)[n]Array index (zero-based)[*]Wildcard (all elements)..Recursive descent (search all levels)[start:end]Array slice[?()]Filter expression

Wildcards and Recursive Descent

The wildcard [*] selects all elements at the current level. The recursive descent operator .. searches through all nested levels of the document:

$..title → all "title" values at any depth

$..price → all "price" values at any depth

$.store.* → all direct children of store

$..* → every single value in the document

Recursive descent is powerful for finding values when you do not know or care about their exact location in the structure. Use it cautiously on large documents since it traverses every node.

Array Slicing

JSONPath supports Python-style array slicing to select a range of elements:

$.books[0:2] → first two books (index 0 and 1)

$.books[-1:] → last book

$.books[::2] → every other book (step of 2)

$.books[1:3] → books at index 1 and 2

Filter Expressions

Filters let you select elements based on conditions. They use the [?()] syntax with @ representing the current element:

// Books cheaper than 40

$.store.books[?(@.price < 40)]

// Books with a specific title

$.store.books[?(@.title == "Clean Code")]

// Books that have an "isbn" field

$.store.books[?(@.isbn)]

// Combined conditions

$.store.books[?(@.price > 30 && @.price < 50)]

Filters are the most powerful feature of JSONPath. They turn simple navigation into actual queries, letting you extract exactly the data you need without writing loops or conditionals in your code.

JSONPath vs XPath

If you have used XPath for XML, JSONPath will feel familiar. Here is a quick comparison:

XPath: /store/books/book[1]JSONPath: $.store.books[0]XPath: //titleJSONPath: $..titleXPath: /store/books/book[@price<40]JSONPath: $.store.books[?(@.price<40)]XPath: /store/*JSONPath: $.store.*

The main difference is that XPath uses 1-based indexing while JSONPath uses 0-based. Also, XPath has a richer set of built-in functions, while JSONPath keeps things minimal.

Using JSONPath in JavaScript

The most popular JavaScript library for JSONPath is jsonpath-plus:

import { JSONPath } from "jsonpath-plus";

const data = { store: { books: [...] } };

const titles = JSONPath({ path: "$.store.books[*].title", json: data });

// ["Clean Code", "Refactoring", "Design Patterns"]

Using JSONPath in Python

Python has several JSONPath libraries. jsonpath-ng is the most feature-complete:

from jsonpath_ng.ext import parse

expr = parse("$.store.books[*].title")

matches = [m.value for m in expr.find(data)]

Real-World Use Cases

  • API testing. Tools like Postman and REST Assured use JSONPath to assert values in API responses without parsing the entire body manually.
  • Data pipelines. Extract specific fields from large JSON payloads in ETL processes. JSONPath expressions can be stored as configuration, making pipelines flexible.
  • Log analysis. Parse structured JSON logs and extract error messages, status codes or user IDs across thousands of log entries.
  • Configuration. Tools like Kubernetes use JSONPath in kubectl get to format output: kubectl get pods -o jsonpath='{.items[*].metadata.name}'
  • Frontend state. Query deeply nested Redux or Zustand state trees to extract specific slices of data for components.

Tips and Best Practices

  • Start simple. Build your expression incrementally. Start with the root, add one level at a time and verify the output at each step.
  • Use bracket notation for special keys. If a key contains dots, spaces or special characters, use ['my.key'] instead of dot notation.
  • Be aware of implementation differences. JSONPath is not formally standardized (though RFC 9535 was published in 2024). Different libraries may handle edge cases differently, especially around filters and recursive descent.
  • Test with real data. Always test your expressions against actual API responses or data files, not simplified examples. Real data has null values, missing fields and unexpected types that can trip up queries.

Test JSONPath expressions online

Paste your JSON data, write a JSONPath query and see matching results instantly. Perfect for debugging and learning JSONPath syntax.

Open JSON Path Tester