Result formats

Responses can return queried data in three formats: JSON, Jolt, or graph.

JSON

The JSON format is the default one, and returns JSON with an embedded results element. To request this format, set Accept: application/json in the request headers (or avoid specifying it all, as it is the default if no Accept header is provided).

JSON output format prototype
{
  "results": [
    {
      "columns": [ columns-list ], (1)
      "data": [
        {
          "row": [ row-data ],  (2)
          "meta": [ entities-metadata ]  (3)
        },
      ]
    },
    {
     //another statement's results
    }
  ]
}
1 Query fields, i.e. keys for the returned objects
2 Results from your query (the inner structure depends on the object type)
3 Metadata for each returned entity (nodes/relationships)

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (p:Person {name: $name}) RETURN p AS person",
      "parameters": {
          "name": "Phil"
      }
    }
  ]
}

Example response

{
  "results": [ {
    "columns": [ "person" ],
    "data": [ {
      "row": [ {
        "name": "Phil"
      } ],
      "meta": [ {
        "id": 11,  (1)
        "elementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:11",  (2)
        "type": "node",  (3)
        "deleted": false  (4)
      } ]
    } ]
  } ],
  // other transactional data
}
1 (Deprecated) Entity ID within the database
2 Entity ID within the database
3 Entity type
4 Whether the entity was deleted in the query (it is true when returning an entity after running Cypher DELETE on it)
elementId should be used with care, as no guarantees are given about the mapping between ID values and elements outside the scope of a single transaction. In other words, using an elementId to MATCH an element across different transactions is risky.

Jolt

Jolt, short for JSON Bolt, is a JSON-based format which encloses the response value’s type together with the value inside a singleton object.

For example, {"Z": "2"} labels the value 2 as an integer type.

To receive the result in this format, set the Accept header as follows:

Accept: application/vnd.neo4j.jolt-v2

Container format

Jolt results are returned in a container format based on events. A typical response looks like the following:

{"header":{"fields":["name","age"]}}
{"data":[{"U":"Bob"},{"Z":"30"}]}
{"data":[{"U":"Alice"},{"Z":"40"}]}
{"data":[{"U":"Eve"},{"Z":"50"}]}
...
{"summary":{}}
{"info":{"commit":"commit/uri/1"}}
Table 1. Container format objects
Event Function

header

Marks the start of a result set for a statement, and contains query fields.

data

One such object for each returned record. Each query can potentially return multiple data objects. The order of values in the array matches the fields received in the header.

summary

Marks the end of a result set for a statement. Contains query plan information, if requested.

info

Final event to appear after processing all statements (unless an error has occurred). Contains transaction information (e.g. commit URI, bookmarks).

error

Errors occurred during the processing of the transaction.

Line feed delimited mode and JSON sequence mode

By default, Jolt is returned in line feed delimited mode. In this mode, each event is a separate JSON document separated by a single LF character (Line Feed, UTF encoding: 0x8A).

Line feed delimited mode encoding example
{"header":{"fields":["result"]}}\n
{"data":[{"Z":"1"}]}\n
{"summary":{}}\n
{"info":{}}\n

The API can also return it in JSON sequence mode (encoded as per RFC 7464). To achieve that, set the Accept header as follows:

Accept: application/vnd.neo4j.jolt-v2+json-seq

In this mode, each event is encapsulated within an RS character (Record Separator/Information Separator Two, UTF-8 encoding: 0x1E) at the beginning of each document as well as a LF character at the end.

JSON sequence mode encoding example
\u001E{"header":{"fields":["result"]}}\n
\u001E{"data":[{"Z":"1"}]}\n
\u001E{"summary":{}}\n
\u001E{"info":{}}\n

Sparse and strict mode

By default, Jolt returns data in sparse mode, which omits type pairing on values which can be matched to JSON types.

In strict mode, all values are paired with their type. To enable strict mode, append ;strict=true to the Accept header:

Accept: application/vnd.neo4j.jolt-v2;strict=true
Accept: application/vnd.neo4j.jolt-v2+json-seq;strict=true

For information on types matching, see Jolt types.

Multiple result sets in a request

When there are multiple queries in a single request, there will be multiple header, data, and summary outputs for each query. Result sets are returned in the same order as specified in the request.

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/vnd.neo4j.jolt-v2
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    { "statement": "RETURN 1 AS resultA" },
    { "statement": "UNWIND range(1,3,1) AS resultB RETURN resultB" }
  ]
}

Example response

200: OK
Content-Type: application/vnd.neo4j.jolt-v2
{"header":{"fields":["resultA"]}}
{"data":[{"Z":"1"}]}
{"summary":{}}
{"header":{"fields":["resultB"]}}
{"data":[{"Z":"1"}]}
{"data":[{"Z":"2"}]}
{"data":[{"Z":"3"}]}
{"summary":{}}
{"info":{}}

Jolt types

This section details how Cypher types are labeled in Jolt.

Base types

Type Label Type Example

(N/A)

null

null

?

Boolean

{"?": "true"}

Z

Integer

{"Z": "123"}

R

Float

{"R": "9.87"} [1]

U

String

{"U": "Neo4j"}

T

Temporal

{"T": "2023-08-09T09:02:40.063Z"}
{"T": "2023-08-09"}
{"T": "09:02:40.063Z"}
{"T": "P14DT16H12M"}

@

Spatial

{"@": "SRID=4326;POINT(1.2 3.4)"}
{"@": "SRID=4979;POINT Z (3.4 5.6 7.8)"}

#

Hexadecimal

{"#": "FA08"}

1. The type label R is used both to indicate floating point numbers and integers outside the range of 32-bit signed integers.

Composite types

Type Label Type Example

[]

List

{"[]": [{"Z": "123"}, …​ ]}

{}

Map

{"{}": {"name": {"U": "Jeff"}, …​}}

Entity types

Node
{"()": [node_id, [ node_labels], {"prop1": "value1", "prop2": "value2"}]}

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/vnd.neo4j.jolt-v2
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (p:Person:Employee {name: 'Phil', age: 21}) RETURN p"
    }
  ]
}

Example response

200: OK
Content-Type: application/vnd.neo4j.jolt-v2
{
  "header": {
    "fields": [
      "p"
    ]
  }
}
{
  "data": [
    {
      "()": [
        "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:12",
        [
          "Person",
          "Employee"
        ],
        {
          "name": "Phil",
          "age": 21
        }
      ]
    }
  ]
}
{
  "summary": {}
}
{
  "info": {
    "lastBookmarks": [
      "FB:kcwQt8DpQx5zR0uN3Oj/OudM3ReQ"
    ]
  }
}
Relationships
{"->": [rel_id, start_node_id, rel_type, end_node_id, {properties}]}
{"<-": [rel_id, end_node_id, rel_type, start_node_id, {properties}]}

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/vnd.neo4j.jolt-v2
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (:Person:Employee {name: 'Phil', age: 21})-[rel:KNOWS {since: 1999}]->(:Person {name: 'Lucy', age: 20}) RETURN rel"
    }
  ]
}

Example response

200: OK
Content-Type: application/vnd.neo4j.jolt-v2
{
  "header": {
    "fields": [
      "rel"
    ]
  }
}
{
  "data": [
    {
      "->": [
        "5:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:7",
        "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:12",
        "KNOWS",
        "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:13",
        {
          "since": 1999
        }
      ]
    }
  ]
}
{
  "summary": {}
}
{
  "info": {
    "lastBookmarks": [
      "FB:kcwQt8DpQx5zR0uN3Oj/OudM3ReQ"
    ]
  }
}
Paths
{"..": [{node_1}, {rel_1}, {node_2}, ..., {node_n}, {rel_n}, {node_n+1}]}

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/vnd.neo4j.jolt-v2
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE path=(:Person:Employee {name: 'Phil', age: 21})-[:KNOWS {since: 1999}]->(:Person {name: 'Lucy', age: 20}) RETURN path"
    }
  ]
}

Example response

200: OK
Content-Type: application/vnd.neo4j.jolt-v2
{
  "header": {
    "fields": [
      "path"
    ]
  }
}
{
  "data": [
    {
      "..": [
        {
          "()": [
            "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:12",
            [
              "Person",
              "Employee"
            ],
            {
              "name": "Phil",
              "age": 21
            }
          ]
        },
        {
          "->": [
            "5:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:7",
            "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:12",
            "KNOWS",
            "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:13",
            {
              "since": 1999
            }
          ]
        },
        {
          "()": [
            "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:13",
            [
              "Person"
            ],
            {
              "name": "Lucy",
              "age": 20
            }
          ]
        }
      ]
    }
  ]
}
{
  "summary": {}
}
{
  "info": {
    "lastBookmarks": [
      "FB:kcwQt8DpQx5zR0uN3Oj/OudM3ReQ"
    ]
  }
}

Graph

The graph format collates all the nodes and relationships from all columns of the result, and also flattens collections of nodes and relationships, including paths. This format is useful to understand the graph structure of nodes and relationships returned by a query.

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "CREATE (bike:Bike {weight: 10}) CREATE (frontWheel:Wheel {spokes: 3}) CREATE (backWheel:Wheel {spokes: 32}) CREATE p1 = (bike)-[:HAS {position: 1}]->(frontWheel) CREATE p2 = (bike)-[:HAS {position: 2} ]->(backWheel) RETURN bike, p1, p2",
      "resultDataContents": ["graph"]
    }
  ]
}

Example response

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [ {
    "columns": [
      "bike",
      "p1",
      "p2"
    ],
    "data": [ {
      "graph": {
        "nodes": [
          {
            "id": "17",
            "elementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:17",
            "labels": [ "Wheel" ],
            "properties": { "spokes": 3 }
          },
          {
            "id": "18",
            "elementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:18",
            "labels": [ "Wheel" ],
            "properties": { "spokes": 32 }
          },
          {
            "id": "16",
            "elementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:16",
            "labels": [ "Bike" ],
            "properties": { "weight": 10 }
          }
        ],
        "relationships": [
          {
            "id": "9",
            "elementId": "5:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:9",
            "type": "HAS",
            "startNode": "16",
            "startNodeElementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:16",
            "endNode": "17",
            "endNodeElementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:17",
            "properties": { "position": 1 }
          },
          {
            "id": "10",
            "elementId": "5:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:10",
            "type": "HAS",
            "startNode": "16",
            "startNodeElementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:16",
            "endNode": "18",
            "endNodeElementId": "4:b7c0e943-1e73-474b-8ddc-e8ff3ae74cdd:18",
            "properties": { "position": 2 }
          }
        ]
      }
    } ]
  } ],
  "errors": [],
  "commit": "http://localhost:7474/db/neo4j/tx/14/commit",
  "transaction": {
      "expires": "Wed, 9 Aug 2023 08:08:35 GMT"
  }
}

You can also combine the default return format together with the graph one. To achieve that, set "resultDataContents": ["row", "graph"] .

As the graph format is not related to how the result body is encoded, it can be coupled with either JSON or Jolt Accept header.