What is JSONPath?
JSONPath is a query language for JSON, analogous to XPath for XML. It lets you select one or more values from a JSON document using a compact path expression — without writing a loop or knowing the exact structure in advance.
JSONPath is used in:
- Postman — extract values from API responses in test scripts
- AWS Step Functions — InputPath, OutputPath, and ResultPath all use JSONPath
- Kubernetes — kubectl jsonpath output format for scripting
- Gatling, k6, RestAssured — API load and contract testing
- Grafana Transformations — extracting fields from JSON data sources
JSONPath Syntax Reference
Every expression starts with $ — the root of the document.
| Expression | Meaning |
|---|---|
$ | Root document |
$.key | Property "key" on the root object |
$.a.b.c | Nested property — a.b.c |
$.arr[0] | First element of array "arr" |
$.arr[-1] | Last element (negative index) |
$.arr[*] | All elements of array "arr" |
$.* | All properties of the root object |
$..name | Recursive descent — "name" anywhere in the document |
$.arr[0:3] | Slice — elements at index 0, 1, 2 |
$.arr[::2] | Every second element |
$.arr[-2:] | Last two elements |
Recursive Descent (`$..key`)
The \.. operator descends into every level of the tree and returns all values with the given key — regardless of how deeply nested they are.
{
"order": {
"id": 1001,
"items": [
{ "product": { "name": "Laptop" }, "qty": 1 },
{ "product": { "name": "Monitor" }, "qty": 2 }
]
}
}$..name → ["Laptop", "Monitor"]
$..qty → [1, 2]No loop needed. The expression works even if the nesting changes in future API versions.
Filter Expressions `[?(@.condition)]`
Filters select array elements matching a condition. The @ refers to the current item being tested:
$.books[?(@.price < 30)] — books under $30
$.users[?(@.status == "active")] — active users only
$.orders[?(@.total >= 1000)] — high-value orders
$.items[?(@.tags)] — items that have a "tags" field
$.items[?(@.discount && @.qty > 5)] — items with discount AND qty > 5Supported comparison operators: ==, !=, <, <=, >, >=
Complete Practical Example
Given this API response:
{
"store": {
"name": "Tech Books",
"book": [
{ "title": "Clean Code", "author": "Martin", "price": 29.99, "inStock": true },
{ "title": "Refactoring", "author": "Fowler", "price": 34.99, "inStock": false },
{ "title": "Design Patterns", "author": "GoF", "price": 39.99, "inStock": true }
]
}
}| Expression | Result |
|---|---|
$.store.name | "Tech Books" |
$.store.book[*].title | ["Clean Code", "Refactoring", "Design Patterns"] |
$..author | ["Martin", "Fowler", "GoF"] |
$.store.book[0].price | 29.99 |
$.store.book[-1].title | "Design Patterns" |
$.store.book[0:2].title | ["Clean Code", "Refactoring"] |
$.store.book[?(@.price < 35)].title | ["Clean Code", "Refactoring"] |
$.store.book[?(@.inStock == true)].title | ["Clean Code", "Design Patterns"] |
$.store.book[?(@.price < 35 && @.inStock)].title | ["Clean Code"] |
JSONPath in JavaScript
// npm install jsonpath-plus
import { JSONPath } from "jsonpath-plus";
const data = { store: { book: [{ title: "Clean Code", price: 29.99 }] } };
// Get all book titles
const titles = JSONPath({ path: "$.store.book[*].title", json: data });
// => ["Clean Code"]
// Get books under $35
const cheap = JSONPath({ path: "$.store.book[?(@.price < 35)]", json: data });JSONPath in Python
# pip install jsonpath-ng
from jsonpath_ng import parse
import json
with open("data.json") as f:
data = json.load(f)
# Find all book titles
expr = parse("$.store.book[*].title")
titles = [match.value for match in expr.find(data)]
print(titles) # => ["Clean Code", ...]
# Filter by price
expr2 = parse("$.store.book[?(@.price < 35)].title")
cheap = [m.value for m in expr2.find(data)]JSONPath in Postman
In Postman test scripts, use pm.response.json() and chain with JSONPath:
// In Postman Tests tab
const data = pm.response.json();
const titles = JSONPath({ path: "$.store.book[*].title", json: data });
pm.test("Returns books", () => pm.expect(titles.length).to.be.above(0));Or use Postman's built-in extraction with pm.response.json().store.book[0].title for simple dot-notation paths.
When to Use JSONPath vs jq
| Tool | Best for |
|---|---|
| JSONPath | API testing tools (Postman, k6), AWS Step Functions, Kubernetes |
| jq | CLI data transformation, shell scripts, one-off queries |
| JavaScript lodash.get | Simple dot-path access in JS code |
| JavaScript optional chaining | Safe property access in TypeScript/JS |
Use JSONKit's JSONPath Tester to interactively test expressions — paste your JSON, type the expression, and see every matching value with its full path in real time.