JSON Pointer

JSON Pointer is a string that identifies one value inside a JSON document — /items/0/name — defined in RFC 6901. It is a list of reference tokens, each prefixed with /, applied from the root one step at a time: an object member by key, or an array element by index.

{
  "build": { "id": "8f2c", "status": "failed" },
  "checks": [
    { "name": "lint", "ok": true },
    { "name": "e2e", "ok": false, "error": "timeout" }
  ],
  "a/b": 1,
  "m~n": 2,
  "": 3
}
Pointer Value
"" the whole document
/build/status "failed"
/checks/1 the e2e object
/checks/1/ok false
/a~1b 1 (key a/b)
/m~0n 2 (key m~n)
/ 3 (the empty key)

The rules

  • The empty string is the root, not /. A lone / means the member whose key is the empty string.
  • Every token is a key or an index. Against an array, the token must be 0 or a decimal number without leading zeros — /checks/01 is an error, not the second element.
  • Two escapes, and only two. ~1 is /, ~0 is ~. Decode ~1 before ~0: the key ~1 is encoded ~01, and decoding in the wrong order turns it into /.
  • - is the slot after the last element. It never resolves to a value; JSON Patch uses it to append.
  • No wildcards, filters or ranges. One pointer, at most one value. A pointer to a key that isn't there fails rather than returning empty.

Two spellings

The plain form above is what JSON Patch and most APIs use. The URI fragment form prefixes # and percent-encodes anything not allowed in a URI fragment:

/build/status          plain
#/build/status         fragment
#/paths/~1users~1{id}  OpenAPI path "/users/{id}" — slashes escaped
#/a%20b                key "a b"

That is why JSON Schema and OpenAPI references look like "$ref": "#/$defs/address" or "#/components/schemas/User" — the part after # is a JSON Pointer into the current document.

Where you meet it

  • JSON Patch (RFC 6902) — every path and from is a pointer: { "op": "replace", "path": "/build/status", "value": "passed" }. See JSON Patch.
  • JSON Merge Patch doesn't use it; it sends a partial document instead.
  • JSON Schema and OpenAPI — $ref fragments, and validators report the failing location as an instance pointer such as /checks/1/ok.
  • Problem Details and API error bodies often name the bad field with a pointer ("pointer": "/data/attributes/email" in JSON:API).
  • Libraries — jsonpointer (Python), json-pointer (npm), nlohmann::json_pointer (C++), Jackson's JsonNode.at() (Java).

JSON Pointer, JSONPath and jq

JSON Pointer JSONPath jq
Spec RFC 6901 RFC 9535 the jq manual
Root "" $ .
Example /checks/1/error $.checks[1].error .checks[1].error
Returns one value a list of matches a stream
Wildcards no [*], .. .[], ..
Filters no ?(@.ok == false) select(.ok == false)
Used to address query query and transform

Rule of thumb: if something has to be changed or referenced at a single location, it is a pointer. If you are looking for values, it is JSONPath or jq.

Getting a pointer without counting brackets

Comma's free JSON viewer folds a document into a tree and copies the path to any node in one click, and the JSON diff lists every change between two documents by path with an RFC 6902 patch you can apply. Both run in your browser, and either can be published as a link reviewers comment on, node by node.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Open the JSON viewer →

Related