{
  "slug": "json-mask",
  "name": "gizza-ai/json-mask",
  "version": "0.1.0",
  "title": "JSON Mask — gizza.ai",
  "description": "Prune a JSON document to just the fields you name with a mask like a,b(c,d) — the Google Partial-Response syntax. Free, in your browser.",
  "tags": [
    "json mask",
    "partial response fields",
    "json field mask",
    "json subtree selector",
    "prune json fields",
    "google fields parameter",
    "remove json fields",
    "strip json keys",
    "json field filter"
  ],
  "category": "data",
  "urls": {
    "page": "https://gizza.ai/tools/json-mask/",
    "markdown": "https://gizza.ai/tools/json-mask/index.md",
    "descriptor": "https://gizza.ai/tools/json-mask/tool.json",
    "deep_link_example": "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"
  },
  "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)'",
  "tool": {
    "description": "Prune a JSON document down to just the fields you name, using the Google Partial-Response / json-mask field syntax — the same 'fields=' language Google and GitHub-style APIs use for partial responses. Unlike JSONPath or jq (which return a flat list of matched nodes), a mask preserves the document's SHAPE: the output is the same object with the unwanted branches removed. Syntax: 'a' keeps a and everything under it; 'a,b,c' keeps siblings; 'a/b/c' follows a path; 'a(b,c)' keeps only b and c inside a; '*' matches every key; '\\' escapes a special character in a key name. Arrays are transparent — 'items(title)' keeps just the title of every element, preserving array order and length. Set mode='remove' to invert the mask and strip the named fields instead (e.g. dropping tokens or PII). on_missing controls absent fields (omit, null, or a loud error), empty='drop' discards elements left empty, and format='compact' emits a single line. Example: mask 'kind,items(title,stats/length)'.",
    "parameters": {
      "additionalProperties": false,
      "properties": {
        "empty": {
          "default": "keep",
          "description": "What to do with objects and array elements left empty by masking. 'keep' (default) keeps the {} husk, matching other implementations. 'drop' removes it, recursively — a container left empty by dropping is dropped too. Use 'drop' when masking a large array where most elements don't have the field.",
          "enum": [
            "keep",
            "drop"
          ],
          "type": "string"
        },
        "format": {
          "default": "pretty",
          "description": "How the result is rendered: 'pretty' (default) is 2-space indented for reading; 'compact' is a single line with no whitespace, for piping into another tool.",
          "enum": [
            "pretty",
            "compact"
          ],
          "type": "string"
        },
        "json": {
          "description": "The JSON document to mask — an object or an array at the top level, e.g. {\"id\":1,\"user\":{\"name\":\"Ada\",\"email\":\"a@x.io\"}}. Maximum 5000000 bytes.",
          "type": "string"
        },
        "mask": {
          "description": "The field mask, in Google Partial-Response / json-mask syntax. 'a' keeps field a and its whole subtree; 'a,b,c' keeps several siblings; 'a/b/c' follows a path; 'a(b,c)' keeps only b and c inside a; '*' is a wildcard matching every key of an object; a backslash escapes a literal , / ( ) * or \\ in a key name. These combine and nest freely: 'kind,items(title,stats/length)'. Arrays are transparent — a selection is applied to every element and the array's length and order are preserved. Maximum 4000 bytes, nested at most 64 levels deep.",
          "type": "string"
        },
        "mode": {
          "default": "keep",
          "description": "What the mask selects. 'keep' (default) returns ONLY the masked fields, pruning everything else while preserving the document's shape. 'remove' inverts it: the masked fields are deleted and everything else is returned — use it to strip tokens or PII, e.g. mask='users(token)' with mode='remove'.",
          "enum": [
            "keep",
            "remove"
          ],
          "type": "string"
        },
        "on_missing": {
          "default": "omit",
          "description": "What to do when the mask names a field the document doesn't have. 'omit' (default) leaves it out, matching every other json-mask implementation. 'null' emits the key with a JSON null so every record has the same shape — handy when masking a list of records for a table. 'error' fails with the field name and its path, which catches a typo'd mask instead of silently returning an empty result. In mode='remove' only 'error' has an effect (there is nothing to omit or null out).",
          "enum": [
            "omit",
            "null",
            "error"
          ],
          "type": "string"
        }
      },
      "required": [
        "json",
        "mask"
      ],
      "type": "object"
    }
  }
}