Headers
#Overview
HTTP headers are a set of key-value pairs included in HTTP requests. They are essential for communicating extra information between the client (you) and the server.
When making GraphQL queries over HTTP, headers are typically used to send important details, like authentication info, content type information, or custom information needed by the server.
Think of HTTP headers as “metadata” for your request, as they carry information about the request itself rather than the actual query content.
Each header has a name (like "Authorization"
) and a value (like "Bearer YOUR_TOKEN_HERE"
).
For example:
Authorization: Bearer YOUR_TOKEN_HEREContent-Type: application/json
#HTTP headers in GraphQL
These are the most commonly used headers in GraphQL:
- Authorization: You need an authorization token for secure API access in Hygraph. You'll use HTTP headers to pass authentication tokens, specifically the
Authorization
header with a Bearer token. This process ensures that only authorized users or systems can access your data.- For example:
Authorization: Bearer YOUR_TOKEN_HERE
- For example:
- Content-Type: This header tells the server what format the request body is in. In GraphQL, it's usually JSON.
- For example:
Content-Type: application/json
- For example:
- Custom Headers: If you need to send any specific info to the server, you can add your own headers. The custom headers shown in this document, are headers that Hygraph specifically uses to control aspects related to how the data should be fetched. While they follow the general structure of HTTP headers, they are unique to Hygraph's API and not standard HTTP headers like
Authorization
orContent-Type
.- For example:
gcms-stage: DRAFT
- For example:
#Add headers to a GraphQL query
The way that you add headers will depend on the tool or language that you're using. Here's how you'd typically add headers in two common ways: using cURL
(a command-line tool) and JavaScript
(fetch API).
Example with cURL
:
curl -X POST -H "Content-Type: application/json" \-H "Authorization: Bearer YOUR_TOKEN_HERE" \-d '{"query": "{ yourQueryHere }"}' \https://your-graphql-api.com/graphql
Example with JavaScript
:
fetch("https://your-graphql-api.com/graphql", {method: "POST",headers: {"Content-Type": "application/json","Authorization": "Bearer YOUR_TOKEN_HERE"},body: JSON.stringify({query: "{ yourQueryHere }"})}).then(response => response.json()).then(data => console.log(data));
The headers
object shown in of both examples above is where we specify the HTTP
headers. Each header will let the server understand the context of your request.
#Custom headers
You can use headers as a global way to send more specific requests to our API. While you could use parameters for this, it is generally easier to dynamically change headers than parameters in a query.
This is where you add headers in the API Playground:
Headers in the API Playground
#gcms-locales
This header works in the same way as using the query input for locales.
You can pass the gcms-locales
header for localized content with your required locales. It is just another way besides the query param to decide which locales a query should return. Basically, the placement is different - header vs. query - but the result is the same. Using one or the other mostly comes down to the developer's preference.
Why use gmcs-locales
instead of the query param then?
To keep queries exactly the same across different environments - production, development, etc. - and then instead of passing the param to the query, you use the header.
In some specific cases passing headers could be easier than putting the params in the query itself.
Example usage 'gcms-locales': 'rb, de, en'
:
const fetch = require('cross-fetch');const headers = {'Content-Type': 'application/json','gcms-locales': 'rb, de, en',};const body = JSON.stringify({ query: '{ products { name } }' });const { products } = await fetch('<your-hygraph-endpoint>', {method: 'POST',headers,body,});
You can also pass an array of locales to gcms-locales
to define your fallback preference.
#gcms-stage
This header works in the same way as using the stage input on a query.
You can pass the gcms-stage
header to specify the stage of your content. It is just another way besides the query param to decide which stage a query should return. Basically, the placement is different - header vs. query - but the result is the same. Using one or the other mostly comes down to the developer's preference.
Why use gcms-stage
instead of the query param then?
To keep queries exactly the same across different environments - production, development, etc. - and then instead of passing the param to the query, you use the header.
In some specific cases passing headers could be easier than putting the params in the query itself.
Example usage 'gcms-stage': 'DRAFT'
:
const fetch = require('cross-fetch');const headers = {'Content-Type': 'application/json','gcms-stage': 'DRAFT',};const body = JSON.stringify({ query: '{ products { name } }' });const { products } = await fetch('<your-hygraph-endpoint>', {method: 'POST',headers,body,});
#hyg-stale-if-error
This header for the High performance endpoint lets you set stale-if-error
on a per query basis.
This cache header can be used to fine-tune our default caching behavior. For instance, we could use it to make sure we return stale data on errors for much longer.
The need to use this header highly depends on the use-case and whether it's important to always get fresh data or to always get data, no matter if stale or new.
Example usage 'hyg-stale-if-error': '21600'
:
const fetch = require('cross-fetch');const headers = {'Content-Type': 'application/json','hyg-stale-if-error': '21600',};const body = JSON.stringify({ query: '{ products { name } }' });const { products } = await fetch('<your-hygraph-endpoint>', {method: 'POST',headers,body,});
The values are in seconds. The default value is 86400
, but this can be adjusted on dedicated clusters if needed.
This is only available on the High performance endpoint.
The default Stale-if-error
for all shared clusters is 86400s (1 day). This value is customizable for dedicated clusters.
To check what your current default is, send a request to the high-performance endpoint and check the response headers called gcms-origin-cache-control
. On a shared cluster, the value of the response header would be similar to this s-maxage=31536000, stale-if-error=86400, stale-while-revalidate=0
.
#hyg-stale-while-revalidate
This header for the High performance endpoint lets you set stale-while-revalidate
on a per query basis.
This cache header can be used to fine-tune our default caching behavior. For instance, we could use it to make sure we return stale data while the cache is revalidating.
The need to use this header highly depends on the use-case and whether it's important to always get fresh data or to always get data, no matter if stale or new.
Example usage 'hyg-stale-while-revalidate': '27'
:
const fetch = require('cross-fetch');const headers = {'Content-Type': 'application/json','hyg-stale-while-revalidate': '27',};const body = JSON.stringify({ query: '{ products { name } }' });const { products } = await fetch('<your-hygraph-endpoint>', {method: 'POST',headers,body,});
The values are in seconds. The default value is 0
, but this can be adjusted on dedicated clusters if needed.
This is only available on the High performance endpoint.
The default stale-while-revalidate
for our shared clusters is 0
. This value is customizable for dedicated clusters.
To check what your current default is, send a request to the high-performance endpoint and check the response headers called gcms-origin-cache-control
. On a shared cluster, the value of the response header would be similar to this s-maxage=31536000, stale-if-error=86400, stale-while-revalidate=0
.
#x-debug-complexity
You can use this header to enable complexity debugging, so the complexity tree is returned.
The possible values are true
& false
.
Example usage 'x-debug-complexity': 'true'
:
const fetch = require('cross-fetch');const headers = {'Content-Type': 'application/json','x-debug-complexity': 'true',};const body = JSON.stringify({ query: '{ products { name } }' });const { products } = await fetch('<your-hygraph-endpoint>', {method: 'POST',headers,body,});