33.7 Over HTTP
| Request | Answer |
|---|---|
POST {url} with { "query", "operationName", "variables" } as application/json |
The result, as application/graphql-response+json. |
POST {url} with the query as the body, Content-Type: application/graphql |
The same. |
GET {url}?query=…&variables=…&operationName=… |
The same, when enableGetRequests is on. Otherwise 405. |
GET {url}?sdl |
The schema as SDL text, when introspection is on. Otherwise 403. |
GET {url} from a browser (Accept: text/html), or ?explorer |
The explorer or the facet page, when switched on (§33.8). |
OPTIONS {url} |
204 with Allow: GET, POST, OPTIONS. |
The status codes are:
200when there isdata, even if some fields failed;400when the request produced no data at all (syntax, validation, variables), or the body is not valid JSON;401when the API key is missing, wrong or expired;503while the database is not open.
Every result carries extensions.durationMs, the time the request took on the server.
API keys. An endpoint with apiKeys needs one of them on every request, in an X-Api-Key
header or as Authorization: Bearer <key>. An expired key gets a 401 that says so, and when
every key has expired, every request is turned away. Give each client its own key. To replace one,
add the new key, move the client over, then remove the key it replaces or let it expire.
curl -s https://example.com/api/graphql -H "Content-Type: application/json" -H "X-Api-Key: $KEY" \
-d '{"query":"query($n:Int){ events(pageSize:$n){ totalCount items { title } } }","variables":{"n":5}}'const response = await fetch("/api/graphql", {
method: "POST",
headers: { "Content-Type": "application/json", "X-Api-Key": apiKey },
body: JSON.stringify({ query, variables: { from: "2026-11-01T00:00:00Z" } }),
});
const { data, errors } = await response.json();The editor's Code view writes typed clients like this for you, in TypeScript and C#.
A browser on another origin needs the application's own UseCors, called before UseRelatudeDB.
The CORS middleware answers the browser's preflight request itself, so the endpoint never sees it.