Skip to content
Back to Learn
·5 min read

Understanding JSON Pointer (RFC 6901): A Complete Guide

JSON Pointer (RFC 6901) is a standardized syntax for identifying specific values within a JSON document. It is used by JSON Schema, JSON Patch (RFC 6902), and many JSON processing libraries. Understanding JSON Pointer is essential for advanced JSON manipulation, error reporting, and schema validation. This guide covers JSON Pointer syntax, escaping rules, usage in APIs, and practical examples. Use our JSON Formatter to visualize pointer paths and JSON Tree Viewer to explore document structure interactively.

JSON Pointer Syntax

A JSON Pointer is a string of path segments separated by / characters. Each segment identifies a property name or array index. The empty string "" refers to the entire document.

PointerPoints ToDocument
""Entire document{"name": "Alice", "age": 30}
/name"Alice"{"name": "Alice"}
/address/city"New York"{"address": {"city": "New York"}}
/tags/0"developer"{"tags": ["developer", "json"]}
/tags/-End of array (append position)JSON Patch add operation
// Example document
{
  "users": [
    {
      "id": 1,
      "name": "Alice",
      "address": {
        "city": "New York",
        "zip": "10001"
      }
    },
    {
      "id": 2,
      "name": "Bob",
      "address": {
        "city": "San Francisco",
        "zip": "94105"
      }
    }
  ]
}

// JSON Pointer examples:
// /users              -> the entire users array
// /users/0            -> the first user object
// /users/0/name       -> "Alice"
// /users/0/address/city -> "New York"
// /users/1/address/zip   -> "94105"

Escaping in JSON Pointer

Special characters in key names must be escaped:

CharacterEscape Sequence
~~0
/~1
// Document with special characters in keys
{
  "~version": 2,
  "key/name": "value",
  "nested": {
    "a/b": "c"
  }
}

// Escaped pointers:
// /~0version       -> 2 (key: ~version)
// /key~1name       -> "value" (key: key/name)
// /nested/a~1b     -> "c" (key: a/b)

// JavaScript implementation
function escapePointer(segment) {
  return segment
    .replace(/~/g, '~0')
    .replace(/\//g, '~1');
}

function unescapePointer(segment) {
  return segment
    .replace(/~1/g, '/')
    .replace(/~0/g, '~');
}

Implementing JSON Pointer Resolution

// JavaScript: Resolve JSON Pointer
function resolvePointer(doc, pointer) {
  if (pointer === '') return doc;

  const segments = pointer.split('/').slice(1); // Remove empty first element
  let current = doc;

  for (const segment of segments) {
    const unescaped = segment.replace(/~1/g, '/').replace(/~0/g, '~');

    if (Array.isArray(current)) {
      const index = parseInt(unescaped, 10);
      if (isNaN(index) || index < 0 || index >= current.length) {
        throw new Error('Invalid array index: ' + unescaped);
      }
      current = current[index];
    } else if (typeof current === 'object' && current !== null) {
      if (!(unescaped in current)) {
        throw new Error('Key not found: ' + unescaped);
      }
      current = current[unescaped];
    } else {
      throw new Error('Cannot descend into ' + typeof current);
    }
  }

  return current;
}

// Usage
const doc = { users: [{ name: "Alice" }] };
resolvePointer(doc, '/users/0/name'); // "Alice"

// Python implementation
def resolve_pointer(doc, pointer):
    if pointer == '':
        return doc
    segments = pointer.strip('/').split('/')
    current = doc
    for segment in segments:
        unescaped = segment.replace('~1', '/').replace('~0', '~')
        if isinstance(current, list):
            current = current[int(unescaped)]
        elif isinstance(current, dict):
            current = current[unescaped]
        else:
            raise ValueError(f"Cannot descend into {type(current)}")
    return current

JSON Pointer in JSON Patch (RFC 6902)

// JSON Patch operations use JSON Pointer for paths
[
  { "op": "replace", "path": "/users/0/name", "value": "Alice Updated" },
  { "op": "add", "path": "/users/0/tags", "value": ["developer"] },
  { "op": "remove", "path": "/users/1/address" },
  { "op": "move", "from": "/users/0", "path": "/users/2" },
  { "op": "copy", "from": "/users/0/address", "path": "/users/1/address" },
  { "op": "test", "path": "/users/0/id", "value": 1 }
]

// Apply patch with json-patch library
const { applyPatch } = require('json-patch');
const result = applyPatch(doc, patch);

JSON Pointer in JSON Schema

// JSON Schema uses JSON Pointer for $ref references
{
  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "city": { "type": "string" },
        "zip": { "type": "string" }
      }
    }
  },
  "properties": {
    "billingAddress": { "$ref": "#/definitions/address" },
    "shippingAddress": { "$ref": "#/definitions/address" }
  }
}

// The #/definitions/address is a JSON Pointer (with document URI prefix)

Common Use Cases

  • Error reporting — Point to the exact field that failed validation
  • Schema references$ref in JSON Schema uses JSON Pointer
  • Patch operations — Every JSON Patch operation specifies a path
  • Data extraction — Extract specific values from large JSON documents
  • Configuration overrides — Override specific nested config values
  • API filtering — Some APIs accept pointers to specify which fields to return

Next Steps

Explore JSON paths visually with JSON Tree Viewer. Format documents with JSON Formatter. Use JSON Patch with JSON Patch Generator and JSON Diff Checker.