Paste a JSON object below to get every key path it contains, including keys buried inside nested objects and arrays. Switch the output between dot notation, value-annotated paths, JSONPath expressions, a nested tree, or a generated TypeScript interface. Everything runs in your browser - your data never leaves this tab.
The quickest way to understand what the tool returns is to see one input mapped to each output format. Take this trimmed-down order response, the kind of payload you get back from a typical e-commerce API:
{
"user": {
"name": "Ada Lovelace",
"address": { "city": "London", "country": { "code": "GB" } },
"roles": ["admin", "engineer"]
},
"orders": [
{ "orderId": "ord_1001", "total": 249.99 },
{ "orderId": "ord_1002", "total": 15.50, "giftMessage": "Happy birthday" }
]
}
Every key, at its literal position. Note that orders appears twice below it because there are two elements in the array.
user
user.name
user.address
user.address.city
user.address.country
user.address.country.code
user.roles
orders
orders[0].orderId
orders[0].total
orders[1].orderId
orders[1].total
orders[1].giftMessage
Repeated indices merge into [] and duplicates are removed. This is the view you want when documenting a schema rather than inspecting one record.
user
user.name
user.address
user.address.city
user.address.country
user.address.country.code
user.roles
orders
orders[].orderId
orders[].total
orders[].giftMessage
Useful when you need to know whether a field is a string, a number, or a container before you write the parsing code.
user object
user.name string
user.address object
user.address.city string
user.address.country object
user.address.country.code string
user.roles array
orders array
orders[].orderId string
orders[].total number
orders[].giftMessage string
Objects inside an array are merged, and any key missing from some elements is marked optional - here giftMessage exists on only one of the two orders.
interface Root {
user: {
name: string;
address: {
city: string;
country: {
code: string;
};
};
roles: string[];
};
orders: {
orderId: string;
total: number;
giftMessage?: string;
}[];
}
Different tools address the same nested value in different ways. This table maps a single field - the city inside the first order's shipping address - across the notations you are most likely to meet.
| Notation | How the path looks | Where you use it |
|---|---|---|
| Dot notation | orders[0].shipping.city |
JavaScript and Python source code, and most ORM or config field mappings. |
| Collapsed dot notation | orders[].shipping.city |
Schema documentation and field-mapping spreadsheets, where the index is noise. |
| JSONPath | $.orders[0].shipping.city |
jq, Postman assertions, API gateway transforms, and many low-code integration tools. |
| JSONPath with wildcard | $.orders[*].shipping.city |
Selecting the same field across every element of an array in one query. |
| Bracket notation | orders[0]["shipping"]["city"] |
Required when a key contains a dot, a space, or a hyphen that would break dot notation. |
| JSON Pointer (RFC 6901) | /orders/0/shipping/city |
JSON Patch documents, JSON Schema $ref targets, and OpenAPI references. |
The one case that trips people up is a key that literally contains a dot. If your JSON has {"user.name": "Ada"}, then the dot-notation path user.name is ambiguous - it could equally describe a nested name inside a user object. Switch to the JSONPath output in that situation, which quotes the key as $['user.name'] and removes the ambiguity.
.json file onto it, or click Load sample JSON to try the tool with a realistic order payload.items[0].sku and items[1].sku into a single items[].sku..txt file (or .ts when you have the TypeScript format selected).| Format | Best for |
|---|---|
| Key paths | Grabbing an exact accessor to paste straight into code, or checking whether a specific field really exists in a response. |
| Key paths with value types | Deciding how to parse a payload - spotting that an id arrives as a string rather than a number before it causes a bug. |
| Unique key names | Building a field glossary, or diffing the vocabulary of two API versions to see which names were added or dropped. |
| JSONPath | Writing jq filters, Postman test assertions, or extraction rules in an integration platform. |
| Indented tree | Getting a visual sense of shape and nesting depth, especially for an unfamiliar payload. This view always collapses array indices, since drawing one branch per element would bury the shape. |
| TypeScript interface | Bootstrapping typed API clients. Treat the result as a first draft to review, not a finished contract - see the limitations below. |
Understand the structure of an unfamiliar API response at a glance instead of scrolling through hundreds of lines looking for the field you need.
Map source fields to destination fields in ETL pipelines and migrations. The collapsed-index view pastes cleanly into a mapping spreadsheet.
Produce a complete flat list of every field, with types, to paste into API docs or share with the team implementing against it.
When a parser cannot find a field, extract the keys to settle whether the field is genuinely absent or simply nested where you did not expect.
No tool fits every job. These are the cases where JSON Keyper will not serve you well, and what to reach for instead:
jq for those.null in your sample is typed null, and a field absent from your sample cannot appear at all. Review the output against the API documentation.number. JSON does not distinguish integers from floats, so the type annotations cannot either.No. All parsing and key extraction happens in JavaScript inside your own browser tab. Your JSON is never transmitted, logged, or stored anywhere. You can confirm this by opening your browser's network tab while using the tool, or by disconnecting from the internet after the page loads - the tool keeps working.
items[0].name?By default JSON Keyper reports the literal path to every key it finds, so an array of three objects produces three separate paths. Tick Collapse array indices to merge them into a single items[].name entry, which is usually what you want when you are documenting a schema rather than inspecting one specific record.
Dot notation such as user.address.city is how you access a value in JavaScript or Python code. JSONPath such as $.user.address.city is a query language understood by tools like jq, Postman, and many API gateways, and it supports wildcards like $.orders[*].total. JSON Keyper can output either.
Files up to a few megabytes are handled comfortably. Because the tool builds the full path list in memory, very large documents (tens of megabytes) may be slow or may exhaust the browser tab's memory. For files that size, a streaming command line tool such as jq is a better fit.
Yes. When an array contains several objects, JSON Keyper merges their shapes and marks any key that is absent from some elements with a question mark. In the built-in sample, giftMessage appears on only one of the two orders, so it is generated as giftMessage?: string.
Dot notation becomes ambiguous when a key name itself contains a dot, because user.name could mean a nested field or a single literal key. The JSONPath output avoids this by quoting such keys in brackets, and the TypeScript output quotes them as string literal keys.
Focused guides for a single output format, each with a worked example:
Longer guides on working with JSON, written alongside this tool: