Queries
Querying Sanity Content Lake with GROQ.
The GROQ query API is located on:
https://<projectId>.api.sanity.io/v<YYYY-MM-DD>/data/query/<dataset>
You can also send queries to the CDN endpoint for edge-cached results:
https://<projectId>.apicdn.sanity.io/v<YYYY-MM-DD>/data/query/<dataset>
projectId
anddataset
can be found in the Sanity Studio configuration file or in the project management dashboard- The
<YYYY-MM-DD>
is the API version you want to target. In most cases, you can use the current date to target the newest API version at the time.
While you can use the HTTP API endpoint directly, we recommend using a client library if you can.
The basic query API endpoint is:
GET /data/query/<dataset>?query=<GROQ-query>
GROQ-queries may also use parameters. In the query, these will be prefixed by a dollar sign ($
) and could look something like this: $language
. These are submitted as normal URL parameters:
GET /data/query/<dataset>?query=<GROQ-query>&$language="es"
Because GROQ needs to know the type of the query param clearly, you need to enclose string values in quotation marks, while numbers and booleans are written in the normal manner:
GET /data/query/<dataset>?query=<GROQ-query>&$string="es"&$bool=true&$number=12.8
Due to limitations in some browsers, we’ve put the max limit on GET queries at 11 KB. If your URL is longer than that, you must submit the query as a POST (see below). Queries sent over POST will also be cached on the CDN.
querystring
the GROQ query itself
explainboolean | "only"
Whether to include the query execution plan as plain text in an explain field, which may be useful when optimizing slow queries. Valid values are
true
(include explain output in result),only
(only return the query plan—do not execute the query), orfalse
(do not include explain output). Note that the plan output is only advisory - the contents are not documented and subject to change without warning.variablesstring
GROQ-queries may also use parameters. In the query these will be prefixed by a dollar sign. These are submitted as normal url-params
resultSourceMapboolean
If true, the query result will include content source map metadata
perspectivestring
Runs the query against the selected perspective:
- 'previewDrafts': query runs as if all draft documents and changes were published
- 'published': query runs as if no draft documents or changes exist
- 'raw': query runs without distinguishing between drafts and published documents
Visit the main documentation article on Perspectives to learn more about this feature.
tagstring
Request tags are values assigned to API and CDN requests that can be used to filter and aggregate log data within request logs from your Sanity Content Lake. Learn more in the request tags documentation.
returnQueryboolean
(Default
true
) Iffalse
, the response will not include the submittedquery
. Only thems
andresult
will be included. Useful for reducing response size.
{
"ms": <server-side processing time>,
"query": <submitted query>,
"result": <query result>
}
Caveat: It is common to assume that the result is always an array of documents, but it isn't. It can be any valid JSON value. If the query is *[_id=="myId"][0]
, the result is the document object unwrapped, for count(*[_type == 'actor' && name match 'weaver'])
the result will be a number. If the query is *[_type == 'actor'].name
, the result is an array of strings (given that the names are strings).
When a document is not found, GROQ still evaluates to a value. Thus, you don't get 404 errors through this endpoint. Some examples:
*[_id == "missing"]
results in[]
count(*[_type == "typoType"])
results in0
*[_id == "missing"][0]
results innull
*[_id == "missing"][0].someProp
also results in null
{
"error": {
"query": "*[",
"description": "Expected ']' following expression",
"start": 1,
"end": 2,
"type": "queryParseError"
}
}
The start
/end
-values correspond to character positions in the submitted query and could be used to provide visual feedback as to where the error occurred. description
is a human-readable description of the error, which may be revised and improved over time and thus should not be used for machine processing while type
is a machine-readable symbol that is intended to be part of the stable API.
Queries longer than 11kB can’t be submitted using the GET method, so they must be POSTed. Queries sent using the POST method will also be cached on the CDN.
POST /data/query/<dataset>
The payload is a JSON document like this:
{
"query": "<the GROQ query>",
// The params-part is optional:
"params": {
"language": "es" // you don't use the $-prefixes when submitting as json
}
}
The results of this endpoint are the same as those of the corresponding GET form described above.