Send a GraphQL query

POST a query and its variables to a GraphQL endpoint to fetch exactly the fields you need in a single request.

Overview

POST a query and its variables to a GraphQL endpoint to fetch exactly the fields you need in a single request.

In code

curl -X POST https://api.example.com/graphql \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{"query":"query($id:ID!){ user(id:$id){ name email } }","variables":{"id":"1"}}'
const res = await fetch('https://api.example.com/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer <token>'
  },
  body: JSON.stringify({
    query: `query($id: ID!) { user(id: $id) { name email } }`,
    variables: { id: '1' }
  })
});
const { data, errors } = await res.json();
if (errors) throw new Error(errors[0].message);
import requests

payload = {
    'query': 'query($id: ID!) { user(id: $id) { name email } }',
    'variables': {'id': '1'},
}
res = requests.post('https://api.example.com/graphql',
                    json=payload,
                    headers={'Authorization': 'Bearer <token>'})
result = res.json()  # {'data': {...}} or {'errors': [...]}

Details

GraphQL is typically a POST to one URL (`/graphql`) with `Content-Type: application/json`, and the body is JSON shaped like `{ "query": "...", "variables": { ... }, "operationName": "..." }`. Do not interpolate values into the query string — pass them via `variables` to avoid injection and to make caching and reuse easy.

The biggest pitfall: GraphQL often returns HTTP 200 even when there are field-level errors. So checking `res.ok` alone is not enough — you must inspect the `errors` array in the body. Real data lives under `data`, and errors under `errors`, and a partial response can carry both.

Auth works like REST, via the `Authorization: Bearer` header. Because reads also use POST, you lose GET caching, so compensate with persisted queries/APQ or a response-cache layer. Subscriptions are usually handled separately over WebSocket or SSE.

Related headers

Related status codes