If you are just getting started with the Sanity query language GROQ, you should probably read the how-to first.

A typical GROQ query has this form:

*[ <filter> ]{ <projection> }

* is a special variable which returns all documents in the dataset that the current user has permissions to read. The documents are passed to a filter, which retains documents for which the expression evaluates to true. The remaining documents are passed to a projection, which determines how the result should be formatted.

A GROQ query of this form operates as a query pipeline, where the results from each component is passed as inputs to the next. The filter and projection are both optional, and a query can have any number of them, in any order, as well as other pipeline components. There are implicit | (pipe) operators between each component, so the query above could equivalently be written as:

* | [ <filter> ] | { <projection> }

In pipeline components, document attributes can be accessed by name. For example, this query would fetch directors born since 1970, and return their name, year of birth, and a list of their movies:

*[ _type == "director" && birthYear >= 1970 ]{
  "movies": *[ _type == "movie" && director._ref == ^._id ]

For a more complete introduction to GROQ, please see the how-to.

JSON Superset

GROQ's syntax is a superset of JSON, so any valid JSON value is a valid GROQ query (that simply returns the given value). Below are a few examples of JSON values:

"Hi! 👋"
["An", "array", "of", "strings"]
  "array": ["string", 3.14, true, null],
  "boolean": true,
  "number": 3.14,
  "null": null,
  "object": {"key": "value"},
  "string": "Hi! 👋"

For more information on JSON syntax, see the JSON specification.


Whitespace is not significant in GROQ, except for acting as a token separator and comment terminator. Any sequence of the following characters is considered whitespace, with Unicode code points in parenthesis:

  • Tab (U+0009)
  • Newline (U+000A)
  • Vertical tab (U+000B)
  • Form feed (U+000C)
  • Carriage return (U+000D)
  • Space (U+0020)
  • Next line (U+0085)
  • Non-breaking space (U+00A0)

Whitespace inside a string literal is interpreted as-is.


Comments serve as query documentation, and are ignored by the parser. They start with // and run to the end of the line:

  // Comments can be on a separate line
  "key": "value" // Or at the end of a line

Comments cannot start inside a string literal.


Literals are inline representations of constant values, e.g. "string" or 3.14. GROQ supports all JSON literals, with a few enhancements and additional data types.

For more information on the data types themselves, see the data types reference.

Boolean and Null Literals

The constants true, false, and null.

Integer Literals

A sequence of digits, e.g. 42. Leading zeroes are ignored.

Float Literals

Floats have an integer part, a fractional part, and an exponent part. The integer part is required, and at least one of the fractional or exponent parts must be given.

The integer part is equivalent to an integer literal. The fractional part is a decimal point . followed by a sequence of digits. The exponent part is e or E followed by an optional + or - sign followed by an integer specifying base-10 exponentiation.

The following are examples of float literals:

3e6      // Equivalent to 3000000.0
3.14eE0  // Equivalent to 3.14
3.14e-2  // Equivalent to 0.0314

String Literals

A sequence of zero or more UTF-8 encoded characters surrounded by single or double quotes, e.g. "Hello world! 👋". The following escape sequences are supported (mirroring JSON), all of which are valid in both single- and double-quoted string literals:

  • \\: backslash
  • \/: slash
  • \': single quote
  • \": double quote
  • \b: backspace
  • \f: form feed
  • \n: newline
  • \r: carriage return
  • \t: tab
  • \uXXXX: UTF-16 code point, where XXXX is the hexadecimal character code
  • \uXXXX\uXXXX: UTF-16 surrogate pair

Array Literals

A comma-separated list of values enclosed by [], e.g. [1, 2, 3]. The final element may be followed by an optional trailing comma.

Object Literals

A comma-separated list of key-value pairs enclosed by {}, where the key and value of each pair is separated by :, e.g. {"a": 1, "b": 2}. Keys must be strings. The final pair may be followed by an optional trailing comma.

Pair Literals

Two values separated by =>, e.g. "a" => 1.

Range Literals

Two values separated by .. (right-inclusive) or ... (right-exclusive), e.g. 1..3.


Identifiers name query entities such as variables, parameters, functions, and some operators. Identifiers must begin with a-zA-Z_, followed by any number of characters matching a-zA-Z0-9_. Parameters are prefixed with $.

Special variables do not use standard identifiers, but are instead denoted by the symbols *, ^, and @.

Reserved Keywords

The following keywords are reserved and cannot be used as identifiers:

  • asc
  • desc
  • false
  • in
  • match
  • null
  • true


GROQ supports unary and binary operators, which return a single value when invoked. Unary operators can be either prefix or postfix (e.g. !true or ref->), while binary operators are always infix (e.g. 1 + 2). Operators are made up of the characters =<>!|&+-*/%, but identifiers can also be used to name certain binary operators (e.g. match), in which case they are considered reserved keywords.


GROQ function calls are expressed as a function identifier immediately followed by a comma-separated argument list in parentheses, e.g. function(arg1, arg2). The final argument may be followed by an optional trailing comma. Functions can take any number of arguments (including zero), and return a single value.

Pipeline Components

Pipelines are constructed by the binary | operator, and are a calling convention by which the output of the left-hand operand is passed to the right-hand operand, such as with * | order(_id). The right-hand operand must be a pipeline component that can accept this kind of piped input. A pipeline component will typically iterate over the piped values and evaluate an expression using variables scoped to each value. For more information on variables and scope, see the Variables section.

Pipeline components can either be filters [<expr>], projections {<...>}, maps (<expr>), or pipeline functions that have the usual function call syntax in addition to the piped input. Projections are fundamentally object literals, but have a wide variety of additional syntactic sugar to make them more pleasant to work with. For more information on projections and other pipeline components, see the Pipeline Components section.

Filters and projections are preceded by an implicit pipe operator, so the | is optional in front of these.


An expression is one of the following:

  • A literal, variable, parameter, or constant
  • An operator invocation (and by extension a pipeline)
  • A function call

An expression can be used anywhere that a value is expected (such as in object values, array elements, operator operands, or function arguments), and is in effect replaced by the value which the expression evaluates to. The exceptions to this are the array element access operator and object attribute access operator, which can only take literals due to parser ambiguity with filters.

Previous: GROQNext: Data Types