How to extract configuration values from json with jsonpath
- Step 1Drop or paste the config — Provide one config document —
appsettings.json,app.config.json, or an exported infrastructure config. It must be a single valid JSON object; comments and trailing commas (common in hand-edited config) will failJSON.parse. - Step 2Write the locate expression — Use
$..connectionStringto find all connection strings,$..enabledto list everyenabledflag, or$.environments[?(@.name == 'production')]to isolate one environment block. - Step 3Handle keys with colons or dashes — ASP.NET-style keys (
Logging:LogLevel) and header keys (x-api-key) work with bracket-quoted notation:$["Logging:LogLevel"]. Dotted notation also tolerates dashes ($.x-api-key) but colons need brackets. - Step 4Run a presence check — Use an existence filter to confirm required keys are set:
$.services[?(@.apiKey)].namelists services that have anapiKeykey. Note it matches even if the value is null — add!= nullor compare to''for stricter checks. - Step 5Verify the matched values — Read the result panel: confirm production URLs are
https, ports are integers, and no value is empty. The match count tells you how many instances were found across the file. - Step 6Reuse in scripts or docs — Copy the values into deployment docs, or reuse the same path in a CI validation step (jq, jsonpath-ng). Download writes a
.extracted.jsonyou can attach to a change record.
Config-query patterns and what they return
Practical JSONPath patterns for auditing JSON configuration. All run against a single config document.
| Goal | JSONPath | Returns |
|---|---|---|
| Every connection string, any depth | $..connectionString | Array of all connection-string values across environments |
All feature flags named enabled | $..enabled | Every enabled boolean wherever it appears |
| The production endpoint only | $.environments[?(@.name == 'production')].endpoint | The single production URL |
| A colon-keyed setting (ASP.NET) | $["Logging:LogLevel"]["Default"] | The default log level string |
| All URLs in a services map | $.services.*.url | Each service's url one level down |
| Services that define an apiKey | $.services[?(@.apiKey)].name | Names of services where the apiKey key is present |
| The whole production block | $.environments[?(@.name == 'production')] | The full production object for review |
Reaching awkward config keys
Config keys often contain characters that plain dot notation can't address. Use brackets for those.
| Key example | Works with | Expression |
|---|---|---|
apiUrl | Dotted | $.apiUrl |
x-api-key | Dotted or bracket | $["x-api-key"] (or $.x-api-key) |
Logging:LogLevel | Bracket only (colon) | $["Logging:LogLevel"] |
AllowedHosts | Dotted | $.AllowedHosts |
ConnectionStrings/Default | Mix | $.ConnectionStrings.Default or $["ConnectionStrings"]["Default"] |
Cookbook
Realistic config shapes with the JSONPath that audits each. Secrets are placeholders; [matches: N] is the count the tool reports.
List every connection string across environments
ExampleMulti-environment configs duplicate connection strings under dev, staging, prod. Recursive descent gathers them all so you can eyeball that none point at the wrong database.
Path: $..connectionString
Input:
{ "environments": {
"dev": { "db": { "connectionString": "Server=dev;..." } },
"prod": { "db": { "connectionString": "Server=prod;..." } }
} }
Output [matches: 2]:
[ "Server=dev;...", "Server=prod;..." ]Isolate the production endpoint
ExampleA single-operator filter picks the environment object by name, then .endpoint projects just the URL — no scrolling through dev and staging entries.
Path: $.environments[?(@.name == 'production')].endpoint
Input:
{ "environments": [
{ "name": "staging", "endpoint": "https://stg.api" },
{ "name": "production", "endpoint": "https://api" }
] }
Output [matches: 1]:
"https://api"Reach an ASP.NET colon-keyed setting
ExampleKeys like Logging:LogLevel can't be addressed with dots because of the colon. Bracket-quoted segments resolve them cleanly.
Path: $["Logging:LogLevel"]["Default"]
Input:
{ "Logging:LogLevel": { "Default": "Warning" } }
Output [matches: 1]:
"Warning"Audit which services are missing an API key
ExampleAn existence filter lists services that HAVE the key; comparing the result count to the total tells you how many are still unset. Existence matches a present key even if null.
Path: $.services[?(@.apiKey)].name
Input:
{ "services": [
{ "name": "billing", "apiKey": "sk_live_x" },
{ "name": "search" }
] }
Output [matches: 1]:
"billing" (search has no apiKey key)Pull every enabled feature flag
ExampleRecursive descent collects every enabled value regardless of where the flag block sits, so you can confirm what's switched on for a release.
Path: $..enabled
Input:
{ "features": {
"newCheckout": { "enabled": true },
"betaSearch": { "enabled": false }
} }
Output [matches: 2]:
[ true, false ]Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Config has comments or trailing commas
Invalid JSONHand-edited config often contains // comments or trailing commas, which strict JSON.parse rejects. Run the file through the json-format-fixer or json-validator first, then extract.
Colon key queried with dot notation
0 matches$.Logging:LogLevel won't resolve — the colon isn't valid in a dotted segment the way the tokenizer reads it. Use bracket-quoted notation: $["Logging:LogLevel"].
Presence check matches a null value
Matched$.services[?(@.apiKey)] keeps a service whose apiKey is null, because existence tests presence only. For a real 'is it set' check, use $.services[?(@.apiKey != null)].
Empty-string value passes the existence check too
MatchedAn apiKey: "" also matches [?(@.apiKey)]. To exclude blanks, compare explicitly: $.services[?(@.apiKey != '')].
Two conditions on one block
0 matches$.environments[?(@.name == 'production' && @.active == true)] is unsupported and returns nothing — there is no &&. Filter by name, then check the second field in the returned object.
Key exists in some env blocks but not others
By design$..featureFlags only returns the blocks that actually have that key; environments missing it simply produce no node. That's the intended way to see which environments define a setting.
Config exceeds the free size limit
BlockedFree tier caps input at 2 MB. A very large multi-environment config beyond that is blocked with an upgrade prompt; Pro raises the limit to 100 MB.
Path resolves to an object, not a scalar
ExpectedIf you stop the path at a block ($.ConnectionStrings) you get the whole object, not a single string. Add the final key ($.ConnectionStrings.Default) to project the scalar you want.
Expecting it to edit or set a config value
Read-onlyThis tool only extracts values — it cannot change them. To rename config keys use json-key-renamer; to strip unwanted keys use json-key-filter.
Frequently asked questions
How do I find a setting no matter how deeply it's nested?
Use recursive descent: $..connectionString (or any key name) returns every occurrence at any depth, which is ideal for multi-environment configs that repeat the same keys per block.
How do I query a key with a colon, like `Logging:LogLevel`?
Use bracket-quoted notation: $["Logging:LogLevel"]. Dot notation can't address the colon. Dashes are fine with dots ($.x-api-key), but colons need brackets.
Can I confirm a required secret is present?
Use an existence filter: $.services[?(@.apiKey)].name. Be aware it matches when the key is present even if the value is null or empty — tighten it with != null or != '' for a real check.
Why did my comment-laced config fail to parse?
JSON.parse is strict: comments, trailing commas, and single quotes throw. Clean the file with the json-format-fixer first, then extract.
Can I filter on environment name and active flag together?
No — only one predicate per filter, and &&/|| aren't supported. Filter on the name, then read the second field from the returned object.
Are my connection strings and keys uploaded?
No. Parsing and JSONPath evaluation run entirely in your browser; no config value is sent to JAD Apps servers.
How do I list every endpoint URL across services?
If services are a map, $.services.*.url returns each one; if they're an array, $.services[*].url. Use $..url to catch URLs at any depth.
What does the wrap-in-array checkbox change?
Off, a single matched value comes back bare (e.g. "Warning"); multiple matches always come back as an array. On, even a single match is wrapped in an array for consistent downstream handling.
How big a config can I process?
Up to 2 MB on the free tier and 100 MB on Pro. Most real configs are well under the free limit.
Can it diff config between two environments?
Not directly — it extracts from one document. Pull the two blocks separately, or use json-diff to compare two config files key by key.
How do I export the extracted values?
Click Copy for the clipboard or Download to save a .extracted.json file (two-space indent). To turn values into a table, send them to json-to-csv.
Does it support YAML config files?
No — it parses JSON only. Convert your YAML first with yaml-to-json, then extract.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.