How to get documents that reference a specific document in GET requests to the Sanity API.

3 replies
Last updated: Oct 5, 2021
When making GET requests to the Sanity api, how can I get documents that reference a specific document?
I've tried two different ways and I always get a 400 error (in my app and in Postman when making the same requests).


Example #1
400 error:

<https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_type> == "registrationForm" && references($id)]&$id="abcdef123456"
But if I remove the
&& references($id)
the request returns all registration form documents with no error:

<https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_type> == "registrationForm"]&$id="abcdef123456"

Example #2
400 error:

<https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_id> == $id]{"registrations": *[_type == "registrationForm" && references(^._id)]}&$id="abcdef123456"
Again, if I remove the references part of the query then it returns correctly with the rest of the user data:


<https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_id> == $id]&$id="abcdef123456"
Can you not use
references()
in HTTP queries or is there some syntax I am missing?
Thank you in advance!
AI Update

The issue you're experiencing is a URL encoding problem. When making GET requests to the Sanity API, special characters in your GROQ query need to be properly URL-encoded, and the && operator is the culprit here.

In GROQ queries sent via HTTP GET requests, you need to encode && as %26%26 (since & has special meaning in URLs as a parameter separator). The Query API documentation specifically mentions this requirement.

Here's how to fix your queries:

Example #1 - Fixed:

https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_type == "registrationForm" %26%26 references($id)]&$id="abcdef123456"

Example #2 - Fixed:

https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_id == $id]{"registrations": *[_type == "registrationForm" %26%26 references(^._id)]}&$id="abcdef123456"

Notice the %26%26 replacing && in both queries.

Better Approach: Use POST Requests

While URL encoding works, a cleaner solution is to use POST requests instead of GET. This avoids URL encoding issues entirely since the query goes in the request body:

fetch('https://mySanityId.api.sanity.io/v2021-06-07/data/query/production', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '*[_type == "registrationForm" && references($id)]',
    params: { id: "abcdef123456" }
  })
})

In Postman, you'd set the method to POST and put your query and parameters in the JSON body.

Using the Sanity Client

If you're working in JavaScript/Node.js, the Sanity client handles all encoding automatically:

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'mySanityId',
  dataset: 'production',
  apiVersion: '2021-06-07',
})

const result = await client.fetch(
  '*[_type == "registrationForm" && references($id)]',
  { id: "abcdef123456" }
)

The references() function works perfectly fine in HTTP queries—you just need to handle the URL encoding properly when using GET requests, or switch to POST to avoid the hassle entirely.

Hi Riley. It could be that your ampersands need to be encoded. Could you try:

<https://mySanityId.api.sanity.io/v2021-06-07/data/query/production?query=*[_type> == "registrationForm" %26%26 references($id)]&$id="abcdef123456"
That did it! I just needed to encode the GROQ query ampersands. Didn't realize that I hadn't been using ampersands in my other requests so it wasn't a problem before.
I'm using RTK Query to make the requests so I'll leave a sample of my code if it is helpful to anyone:


import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const userRegistrationsQuery = `
  *[_type == 'addRegistrationForm' %26%26 references($id)]
`

export const sanityApi = createApi({
  reducerPath: 'sanityApi',
  baseQuery: fetchBaseQuery({ 
    baseUrl: `https://${process.env.SANITY_PROJECT_ID}.<http://api.sanity.io/v2021-06-07/data/query/production|api.sanity.io/v2021-06-07/data/query/production>` 
  }),
  endpoints: (builder) => ({
    getUserRegistrations: builder.query({
      query: (id) => `?query=${userRegistrationsQuery}&$id="${id}"`
    }),
  }),
})

export const {useGetUserRegistrationsQuery} = sanityApi

Awesome! Thanks for the follow-up and leaving the snippet for others. 😄

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?