Explore · JSON Path Finder

JSON Path Finder

Paste JSON and get every path in the document — dot notation with array indexes, each with its value — ready to copy into your code. Runs in your browser.

No sign-up to start · Runs in your browser

JSON Path Finder
Open in full editor
Input
Paths

Runs entirely in your browser — nothing is uploaded.

{"order":{"id":"ord_9412","items":[{"sku":"tee","qty":2},{"sku":"mug","qty":1}],"customer":{"name":"Ada","vip":true}}}
A JSON path finder answers the question you keep asking while coding against a payload: what is the exact path to this value? Paste your JSON and every leaf in the document becomes one path = value line — dot notation for object keys, zero-based bracket indexes for arrays (order.items[1].sku) — ready to copy into JavaScript, Python, or jq. Everything runs in your browser: no account, no upload, and your data never leaves your device.

Every path in an order payload

Input — nested JSON
{
  "order": {
    "id": "ord_9412",
    "items": [
      { "sku": "tee", "qty": 2 },
      { "sku": "mug", "qty": 1 }
    ],
    "customer": { "name": "Ada", "vip": true }
  }
}
Output — 7 paths found
order.id = "ord_9412"
order.items[0].sku = "tee"
order.items[0].qty = 2
order.items[1].sku = "mug"
order.items[1].qty = 1
order.customer.name = "Ada"
order.customer.vip = true

One line per leaf value, in the same depth-first order as the document: all of items[0] before items[1]. Strings keep their JSON quoting, numbers and booleans appear bare, and order.items[0].sku is the exact expression JavaScript accepts after your variable name.

How to find JSON paths

  1. 1

    Paste your JSON

    Drop the payload into the input — an API response, a config file, a log record — or start from the loaded example.

  2. 2

    Make sure it parses

    Path listing needs valid JSON. If the input is rejected, run it through the JSON Repair tool first to fix trailing commas, single quotes, and unquoted keys.

  3. 3

    Read the path list

    Each leaf value becomes one line: the full dot-notation path, an equals sign, then the value. Empty objects and arrays get their own lines too.

  4. 4

    Copy the path you need

    The paths are already valid JavaScript accessors. For Python, turn each key into a quoted subscript — indexes stay bare; for jq, prefix a dot.

  5. 5

    Go visual when lines are not enough

    Open the same JSON in the full editor to click through it as a collapsible tree or mind map, with formatting and validation alongside.

Why use a path finder

Every path, one list

The whole document flattens into path = value lines — nothing to expand, hover, or hunt through.

Array indexes included

Array elements use zero-based bracket notation (items[1].sku), exactly the way your code will access them.

Values shown inline

Each line carries the value in its JSON form, truncated near 60 characters so one giant string cannot wreck the layout.

Root marker for arrays

When the top level is an array or a bare scalar, paths start at $ — so $[0].sku tells you instantly there is no wrapper object.

Runs in your browser

Path listing is 100% client-side; your JSON never leaves your device.

Pairs with the tree view

Carry the same document into the editor to explore it visually when the list gets long.

How to read the path list

Every line describes one leaf value: the full path, an equals sign, then the value. Object keys join with dots (order.customer.name) and array elements append a zero-based index in brackets (order.items[1].sku). The list is depth-first in document order, so it reads top to bottom in the same sequence as the JSON itself — every path under items[0] appears before the first path under items[1], which makes it easy to eyeball one record at a time.

The $ root marker appears when there is no object key to start a path from. A top-level array lists $[0].sku and $[1].sku; a document that is a single bare string or number collapses to one line, $ = value; a document that is just {} or [] prints $ = {} or $ = []. When the top level is a non-empty object, paths start directly at the first key — order.id, not $.order.id — because that is exactly what you will type after a variable name in code.

Two details keep the list honest. Empty containers are not silently dropped: an empty object prints as path = {} and an empty array as path = [], so a key that exists-but-is-empty never masquerades as missing. And values are rendered in their JSON form — strings keep their double quotes, so "2" and 2 stay distinguishable at a glance — but anything longer than about 60 characters is cut with an ellipsis so a giant embedded blob cannot break the one-line-per-path layout.

Using a path in JavaScript, Python, and jq

In JavaScript the copied path works verbatim after your variable name: obj.order.items[0].sku. If any branch might be absent, switch to optional chaining — obj.order?.items?.[0]?.sku — which yields undefined instead of throwing. Utility libraries take the path as a string: Lodash's _.get(obj, "order.items[0].sku") accepts the exact path this tool prints, which makes the list a copy-paste source for config lookups and defensive reads alike.

Python has no dot access on dicts, so each segment becomes its own subscript: data["order"]["items"][0]["sku"] — quote the keys, leave the array index bare. A missing key raises KeyError, so for optional branches chain .get() calls (data.get("order", {}).get("id")) or reach for a path library like glom, which accepts the dotted string "order.items.0.sku" directly.

For jq on the command line, prefix the path with a dot: jq '.order.items[0].sku' response.json. Keys that are not plain identifiers need quotes inside the expression, as in ."content-type". Notice what stays constant across all three: the segment names and index positions never change, only the punctuation around them. That is why one canonical dot-and-bracket list is enough to feed every runtime you work in.

Path list vs JSONPath: enumerate, then select

JSONPath is a query language. An expression like $.store.book[?(@.price < 10)].title describes values by their properties, and an engine returns whichever ones match — with wildcards ($.items[*].sku), recursive descent ($..price), and filter predicates along the way. It is the right tool when you already know the document's shape and want to select from it programmatically.

A path finder inverts that. There is no query to write: it enumerates every concrete path that exists in this specific document, with the value sitting at each one. That is the operation you actually need when staring at an unfamiliar payload, because you cannot write a correct selector for a structure you have not seen yet. Enumeration answers the prior question — what is here, and what is it called.

The two compose naturally. Find the concrete path in the list, then generalize it into a query by prefixing $. and widening the parts that should vary: order.items[0].sku becomes $.order.items[*].sku to select every SKU, or $.order.items[?(@.qty > 1)].sku to filter. The enumerated list is the ground truth; the JSONPath expression is the abstraction you build on top of it.

Tips for huge documents

The output is plain text, so bring text tools to it. Ctrl+F for a value you already know — "ord_9412" — and the line it sits on hands you the path: reverse lookup, the one thing collapsible tree UIs make tedious. Searching for a key fragment like .sku = shows every location where that field occurs, which immediately reveals whether it always lives at the same depth and always holds the same type.

The list doubles as a structural profile. The status line reports the total path count, and the highest index printed under items[ tells you the array's length without scrolling — the last element is items[7], so there are eight. Because only paths that actually exist are printed, comparing the lines under items[0] against items[7] exposes records with missing fields — an absent line is an absent key, which is precisely the kind of inconsistency that breaks mappers and deserializers in production.

When the job shifts from looking up one path to understanding the whole shape, lines stop being the best medium. The button above the output carries the same JSON into the full editor, where you can walk it as a collapsible tree or a mind map, format and validate it, and ask the AI copilot to explain unfamiliar fields — AI actions use credits, and new accounts start with 1,000.

Frequently asked questions

Is the JSON path finder free?

Yes. It runs entirely in your browser with no account and no upload — your JSON never leaves your device.

What path format is used?

Dot notation for object keys and zero-based bracket indexes for arrays — order.customer.name, order.items[0].sku. The document root is written as $ only when there is no key to start from: a top-level array, a bare scalar, or a completely empty document.

How do I use a path in JavaScript, Python, or jq?

JavaScript accepts the path verbatim: obj.order.items[0].sku. Python subscripts each segment: data["order"]["items"][0]["sku"]. jq wants a leading dot: .order.items[0].sku. The segments never change — only the punctuation around them.

How is this different from JSONPath queries?

JSONPath is a query language ($.store.book[?(@.price < 10)]) for selecting values you describe. This tool goes the other way: it enumerates every concrete path that actually exists in your document, so you can see what is there before you write any query.

What happens with empty objects and arrays?

They are listed, not dropped. An empty object prints as path = {} and an empty array as path = [], so you can tell "the key exists but is empty" apart from "the key is missing".

Why do some values end with an ellipsis?

Values longer than about 60 characters are truncated with … so every line stays scannable. Only the display is shortened — copy the full value from your source or from the editor.

What if my JSON is a top-level array?

Paths start at the $ root marker: $[0].sku, $[1].sku, and so on. A document that is a single bare scalar produces one line, $ = value.

What about keys that contain dots or spaces?

The list joins segments with literal dots, so a key like "content.type" is printed dot-joined and reads ambiguously. In code, switch that segment to bracket access — obj.headers["content.type"] in JavaScript — since plain dot syntax cannot express it.

Related tools

Find your paths now

Open the Editor