JSONPath is the XPath of the JSON world — a compact language for extracting values from JSON documents. This tutorial covers every JSONPath operator with practical examples you can run in our JSONPath tester.

Why JSONPath exists

When you have a JSON response from an API and need a specific subset — all user emails, every product over $100, the third element of the second array — you have two options. Write nested loops and conditionals in your code, or write a single JSONPath expression.

JSONPath is much shorter. Compare:

// Imperative
const emails = [];
for (const user of data.users) {
  if (user.active) emails.push(user.email);
}

// JSONPath
$.users[?(@.active==true)].email

For complex extractions, JSONPath is dramatically more compact than the equivalent code.

Operators reference

Every JSONPath expression starts with $, the root of the document. Operators chain after it.

OperatorMeaningExample
$Root$
.nameChild by name$.user.name
['name']Child by name (bracket)$['key-with-dash']
[*]Wildcard (all)$.users[*]
..Recursive descent$..price
[2]Array index$.items[0]
[a:b]Slice$.items[0:3]
[?()]Filter$.users[?(@.age>18)]
[a,b]Union$['name','email']

Working example

We'll use this dataset throughout:

{
  "store": {
    "books": [
      { "title": "Norwegian Wood", "author": "Murakami", "price": 12.99, "isbn": "978-0099448822" },
      { "title": "Brave New World", "author": "Huxley", "price": 9.99 },
      { "title": "1984", "author": "Orwell", "price": 14.50, "isbn": "978-0452284234" },
      { "title": "The Trial", "author": "Kafka", "price": 8.50 }
    ],
    "bicycle": {
      "color": "red",
      "price": 199.99
    }
  }
}

Basic child access

$.store.bicycle.color"red"

$.store.books[0].title"Norwegian Wood"

All elements of an array

$.store.books[*].title["Norwegian Wood", "Brave New World", "1984", "The Trial"]

Recursive descent

$..price[12.99, 9.99, 14.50, 8.50, 199.99] — every "price" field anywhere in the tree.

Slices (Python-style)

$.store.books[0:2] → first two books

$.store.books[-2:] → last two books

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

Filters

$.store.books[?(@.price < 10)] → books cheaper than $10

$.store.books[?(@.isbn)] → books that have an ISBN field

$.store.books[?(@.author=="Orwell")].title → titles by Orwell

Filter expressions support: ==, !=, <, <=, >, >=, and logical &&, || (in most implementations).

Unions

$.store.books[0,2].title → titles of books 0 and 2

$.store.books[*]['title','price'] → title and price of every book

Real-world examples

Extract all error messages from a nested response:

$..error

Get the email of every active user:

$.users[?(@.active==true)].email

Get product names in stock under $100:

$.products[?(@.stock>0 && @.price<100)].name

Get the last 3 orders:

$.orders[-3:]

Get cities of every user's address:

$.users[*].address.city

JSONPath vs jq

jq is more powerful — it can transform and aggregate, not just select. The same query in both:

# JSONPath
$.users[?(@.active==true)].email

# jq
.users[] | select(.active==true) | .email

For pure extraction, JSONPath is simpler to learn. For complex pipelines that need filtering, mapping, and aggregation, jq is more capable. They aren't replacements — they're complementary tools.

JSONPath vs JMESPath

JMESPath is AWS's preferred JSON query language, used in the AWS CLI's --query parameter. The syntax is similar but not identical. JMESPath is more structured (and has a formal spec) but less widely supported. If you work primarily with AWS tools, learn JMESPath. Otherwise, JSONPath is the safer bet.

Dialect variations

JSONPath was specified informally by Stefan Goessner in 2007. Most implementations follow that informal spec, but they diverge on details:

IETF RFC 9535 (2024) formalizes a strict subset. As implementations adopt it, dialect variations should reduce.

Testing your expressions

The fastest way to learn JSONPath is to experiment. Our JSONPath tester shows results instantly as you type the expression — paste a sample JSON, then try different paths to see what matches. After 10 minutes of play, the syntax becomes second nature.

Wrap-up

JSONPath is one of the highest-leverage skills for anyone who consumes JSON APIs. A few minutes of learning saves hours of writing extraction loops. Start with the basic operators (., [*], ..) — they cover 80% of real queries. Add filters when you need conditional selection.