API reference

Query JSON with JMESPath

Evaluate a JMESPath expression against JSON and return the result, its type and pretty JSON.

GET POST /api/json/query MCP tool json_query

Evaluates expression against input with @jmespath-community/jmespath (JMESPath Community Edition): the original JMESPath language plus let expressions, $ for the root, arithmetic (+ - * / % //), the ternary ? : operator, and extra functions such as items, from_items, group_by, zip, find_first, pad_left, split, replace, trim. A path that does not exist gives null (not an error). Syntax errors give the column of the offending token; unknown functions are reported before evaluation; type errors (for example length of a number) are reported with the function position.

Browser version (runs locally): JMESPath Query.

Try it

Credentials
Remember these credentials

Not saved: you will paste them again next time.

No credentials yet? Get a client ID and secret. They are sent only to this site, in an Authorization: Basic header.

POST /api/json/query with a JSON body

Parameters

Parameter Type Default Description
input required string (≤ 500000 chars) — The JSON document, as JSON text (string field or raw text/plain POST body).
expression required string (≤ 2048 chars) — The JMESPath expression, e.g. sort_by(items, &price)[-1].name. JSON literals are written between backtick characters; raw strings go in single quotes.
indent 2 | 4 | tab | none 2 JSON output indentation: 2 or 4 spaces, tab, or none for minified output (no whitespace at all).

Also accepted on every endpoint: format (json | text). Parameters may come from the query string, a JSON object body, an urlencoded or multipart form, or (for input) a text/plain body.

Global parameters
Parameter Type Default Description
format json | text json json returns the documented object. text returns only the primary value as text/plain (see "Text output").

Response 200 application/json

Field Type Description
result any The result as a JSON value (null when nothing matched).
type "object" | "array" | "string" | "number" | "boolean" | "null" JSON type of the result.
json string The result as JSON text, formatted per indent.
warnings array of object Valid-but-risky findings: integers beyond 2^53 − 1, numbers that overflow a double, unpaired surrogate escapes, duplicate keys. At most 100 are listed.
warnings[].message string Plain-language finding.
warnings[].pointer string JSON Pointer of the value concerned.
warnings[].line integer 1-based line number.
warnings[].column integer 1-based column, counted in Unicode code points.
warnings[].offset integer 0-based offset in code points.

Text output (format=text, text/plain): The result as JSON text.

Errors

Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.

Status Code When
422 unprocessable_input input is not valid JSON (line, column and offset given); expression has a syntax error (column given) or calls an unknown function; or evaluation fails (a function received the wrong type, division by zero, a slice step of 0).
400 invalid_parameter input exceeds 500,000 characters or expression exceeds 2,048.
400 missing_parameter A required parameter is absent.
400 unknown_parameter A parameter name is not in the table above (typos are rejected, not ignored).
413 payload_too_large The request body exceeds 1 MiB.
405 method_not_allowed A method other than GET, POST or OPTIONS.

Behaviour

  • Idempotent: the same arguments always return the same result.
  • Requires a client ID and secret (authentication). Each call is recorded as one metadata row against your client ID; inputs and outputs are never stored or logged. Responses carry cache-control: no-store.
  • CORS: any origin may call this endpoint from a browser, using your credentials.

Examples

Responses below were produced by running each request through this code at build time. Long strings are shortened.

Filter and project

curl -X POST 'https://util.caruana.me/api/json/query' \
  -H 'content-type: application/json' \
  -d '{"input":"{\"items\":[{\"name\":\"a\",\"price\":5,\"tags\":[\"x\"]},{\"name\":\"b\",\"price\":12,\"tags\":[\"x\",\"y\"]},{\"name\":\"c\",\"price\":30,\"tags\":[]}]}","expression":"items[?price > `10`].name"}'

Response 200

{
  "result": [
    "b",
    "c"
  ],
  "type": "array",
  "json": "[\n  \"b\",\n  \"c\"\n]",
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "json_query",
    "arguments": {
      "input": "{\"items\":[{\"name\":\"a\",\"price\":5,\"tags\":[\"x\"]},{\"name\":\"b\",\"price\":12,\"tags\":[\"x\",\"y\"]},{\"name\":\"c\",\"price\":30,\"tags\":[]}]}",
      "expression": "items[?price > `10`].name"
    }
  }
}

Sort, slice and reshape

curl -X POST 'https://util.caruana.me/api/json/query' \
  -H 'content-type: application/json' \
  -d '{"input":"{\"items\":[{\"name\":\"a\",\"price\":5},{\"name\":\"b\",\"price\":12},{\"name\":\"c\",\"price\":30}]}","expression":"sort_by(items, &price)[-2:].{name: name, cost: price}"}'

Response 200

{
  "result": [
    {
      "name": "b",
      "cost": 12
    },
    {
      "name": "c",
      "cost": 30
    }
  ],
  "type": "array",
  "json": "[\n  {\n    \"name\": \"b\",\n    \"cost\": 12\n  },\n  {\n    \"name\": \"c\",\n    \"cost\": 30\n  }\n]",
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "json_query",
    "arguments": {
      "input": "{\"items\":[{\"name\":\"a\",\"price\":5},{\"name\":\"b\",\"price\":12},{\"name\":\"c\",\"price\":30}]}",
      "expression": "sort_by(items, &price)[-2:].{name: name, cost: price}"
    }
  }
}

Count and aggregate

curl -X POST 'https://util.caruana.me/api/json/query' \
  -H 'content-type: application/json' \
  -d '{"input":"{\"items\":[{\"price\":5},{\"price\":12},{\"price\":30}]}","expression":"{count: length(items), total: sum(items[].price), max: max(items[].price)}","indent":"none"}'

Response 200

{
  "result": {
    "count": 3,
    "total": 47,
    "max": 30
  },
  "type": "object",
  "json": "{\"count\":3,\"total\":47,\"max\":30}",
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "json_query",
    "arguments": {
      "input": "{\"items\":[{\"price\":5},{\"price\":12},{\"price\":30}]}",
      "expression": "{count: length(items), total: sum(items[].price), max: max(items[].price)}",
      "indent": "none"
    }
  }
}