JSON Mask

Paste a JSON document and a field mask like kind,items(title,stats/length) to get back the same document with everything else pruned away — paths, sub-selections, wildcards and array mapping included. Invert the mask to strip tokens or PII instead. Runs entirely in your browser, no server, no sign-up.

Masked JSON

About this tool

A field mask is the little language Google's Partial Response fields= parameter uses: kind,items(title,stats/length). It says which parts of a JSON document you care about, and the document comes back with everything else pruned away.

That last part is what makes a mask different from JSONPath, jq or JSONata. Those return a flat list of the nodes that matched. A mask preserves the shape of the document: the same object, at the same nesting, minus the branches you didn't ask for. If you are trimming an API response down to the handful of fields a client actually reads, the shape is exactly what you want to keep.

Mask syntax

FormMeaning
akeep a and its entire subtree
a,b,ckeep several siblings
a/b/cfollow a path — keep c inside b inside a
a(b,c)sub-selection — from a, keep only b and c
*wildcard — match every key of an object
\, \/ \( \) \* \\escape a literal special character inside a key name

These nest and combine freely. Arrays are transparent: a selection applied to an array is applied to every element, and the array's length and order survive untouched.

Worked example

Mask kind,items(title,stats/length) over

{
  "kind": "list",
  "etag": "W/\"9a1\"",
  "items": [
    { "title": "First", "author": "Ada", "stats": { "length": 120, "views": 3 } },
    { "title": "Second", "author": "Grace", "stats": { "length": 80, "views": 9 } }
  ]
}

gives

{
  "kind": "list",
  "items": [
    { "title": "First", "stats": { "length": 120 } },
    { "title": "Second", "stats": { "length": 80 } }
  ]
}

etag, author and views are gone; kind and both array elements stay where they were.

Beyond the standard grammar

The four selects add the things a one-shot tool needs that a library doesn't:

Everything runs in WebAssembly inside your browser tab. The document you paste is never uploaded, and key order is preserved exactly as you wrote it.

FAQ

How is a field mask different from JSONPath or jq?

JSONPath and jq are query languages: they evaluate an expression and hand back the nodes that matched, usually as a flat list. A field mask is a pruning language: the result is the original document with the unselected branches removed, at the same paths and in the same order. Use a mask when the consumer still expects the document's shape — trimming an API response, for instance — and jq when you want to reshape or compute.

Why did `a` keep everything under `a` instead of just `a` itself?

That is the defined behaviour of the grammar: a bare name selects the field and its whole subtree. To prune inside it you have to say so with a sub-selection — a(x,y) — or a path like a/x. So items keeps every field of every element, while items(title) keeps only each element's title.

Do arrays need an index in the mask?

No. Arrays are transparent to a mask. Write the selection as though the array were a single object and it is applied to every element, preserving the array's order and length. There is no way to select element 3 specifically — that is a query, not a mask, and jq or JSONPath is the right tool for it.

My mask returned `{}` or almost nothing. What went wrong?

Almost always a name that doesn't exist in the document — a typo, or the wrong case. Absent fields are omitted silently by default, so a completely wrong mask looks like a working mask with nothing to show. Set the missing-fields option to "Fail with an error" and the tool names the offending field and the path it was looked for at.

Can I use this to strip secrets or PII out of a payload?

Yes — that is what remove mode is for. Write a mask that names the fields you want gone, switch the mode to remove, and you get the whole document back minus exactly those fields: token, users(email,phone), */password. Because the tool runs locally in your browser, the payload never leaves the machine while you do it.

Is there a size limit?

The document can be up to 5,000,000 bytes and the mask up to 4,000 bytes, nested at most 64 levels deep. Those ceilings exist to keep a pathological input from hanging the tab; ordinary API responses are nowhere near them.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool json-mask '{"kind":"list","etag":"W/\"9a1\"","items":[{"title":"First","author":"Ada","stats":{"length":120,"views":3}},{"title":"Second","author":"Grace","stats":{"length":80,"views":9}}]}' 'mask=kind,items(title,stats/length)'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/json-mask/?json=%7B%22kind%22%3A%22list%22%2C%22etag%22%3A%22W%2F%5C%229a1%5C%22%22%2C%22items%22%3A%5B%7B%22title%22%3A%22First%22%2C%22author%22%3A%22Ada%22%2C%22stats%22%3A%7B%22length%22%3A120%2C%22views%22%3A3%7D%7D%2C%7B%22title%22%3A%22Second%22%2C%22author%22%3A%22Grace%22%2C%22stats%22%3A%7B%22length%22%3A80%2C%22views%22%3A9%7D%7D%5D%7D&mask=kind%2Citems%28title%2Cstats%2Flength%29&mode=keep&format=pretty&on_missing=omit&empty=keep

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.