DevTools Hub

Search tools

Search for a developer tool

JSONPath Examples

Part of the JSON Toolkit

A reference collection of expressions against realistic JSON shapes — not the syntax behind them (see What Is JSONPath? for that). Every expression here is verified against real data with JSONPath Plus, the same library behind JSONPath Tester.

An API response

{
  "data": {
    "users": [
      { "id": 1, "name": "Ada", "roles": ["admin", "editor"], "active": true },
      { "id": 2, "name": "Grace", "roles": ["editor"], "active": false },
      { "id": 3, "name": "Alan", "roles": ["viewer"], "active": true }
    ]
  },
  "meta": { "page": 1, "totalPages": 5 }
}
ExpressionResult
$.data.users[*].name["Ada","Grace","Alan"]
$.data.users[?(@.active==true)].name["Ada","Alan"]
$.data.users[?(@.roles.indexOf('admin')!==-1)].name["Ada"]

JSONPath has no built-in "array contains" operator, so the third row's pattern — .indexOf(x) !== -1 inside a filter — is the idiomatic way to check whether a value is a member of an array field, here matching only the user whose roles array includes "admin".

Finding a field anywhere, regardless of structure

{
  "server": { "port": 8080, "timeout": 30 },
  "database": { "port": 5432, "timeout": 10 },
  "cache": { "redis": { "port": 6379 } }
}
ExpressionResult
$..port[8080,5432,6379]
$..timeout[30,10]

$.cache.redis.port is three levels deep while $.server.port is two — $..port doesn't care about the difference. This is the pattern worth reaching for whenever a config file's exact shape might change but the field name you care about won't.

Filtering log entries

{
  "entries": [
    { "level": "info", "msg": "started" },
    { "level": "error", "msg": "failed", "code": 500 },
    { "level": "error", "msg": "not found", "code": 404 },
    { "level": "warn", "msg": "slow" }
  ]
}
ExpressionResult
$.entries[?(@.level=='error')].msg["failed","not found"]
$.entries[?(@.code>=500)].msg["failed"]

The second row combines a numeric comparison with the fact that not every entry even has a code field — entries missing it simply don't match, the same no-error-on-a-missing-field behavior covered in JSONPath Tester's FAQ.

The end of an array

{ "commits": ["a1", "b2", "c3", "d4", "e5"] }
ExpressionResult
$.commits[-1:]["e5"]
$.commits[-2:]["d4","e5"]
$.commits[:2]["a1","b2"]
$.commits[::2]["a1","c3","e5"]

Slice syntax is [start:end:step], straight from Python — a negative start counts from the end, an omitted end means "through the end," and the last row's step of 2 takes every other element.

Flattening nested arrays

{ "rows": [{ "cells": [1, 2] }, { "cells": [3, 4] }] }
ExpressionResult
$.rows[*].cells[*][1,2,3,4]

Chaining two wildcards walks every row, then every cell inside each row, and returns them as a single flat list rather than a list of lists — useful whenever you need the leaf values only and don't care which row each one came from.

Computed indices with a script expression

{ "items": ["a", "b", "c", "d"] }
ExpressionResult
$.items[(@.length-1)]["d"]

[(expr)] evaluates expr against the current node — here, @.length-1 computes the last valid index without hardcoding the array's length. It does the same job as [-1] above; reach for the script form when the index you need is computed rather than a fixed offset from either end. See What Is JSONPath? for a security note on this syntax before running it against untrusted expressions.

Combining recursive descent with a filter

{
  "departments": [
    { "name": "eng", "employees": [{ "name": "Ada", "level": 5 }, { "name": "Grace", "level": 3 }] },
    { "name": "sales", "employees": [{ "name": "Alan", "level": 4 }] }
  ]
}
ExpressionResult
$..employees[?(@.level>=4)].name["Ada","Alan"]

$..employees finds the employees array inside every department without naming any department, and the filter that follows applies independently within each one — no need to know in advance how many departments exist or what they're called.

Try it yourself

Paste any of these into JSONPath Tester along with your own data, or click through a document with JSONPath Generator to get the expression for a specific value instead of writing one by hand. Both run entirely in your browser.

Related tools