Extract GraphQL query variable names and types
This GraphQL variable extractor reads an executable GraphQL document, checks its syntax, and lists every variable declared by each query, mutation, or subscription.
Run — free
Each result preserves the operation kind, optional operation name, variable name, and exact type notation, including lists and non-null markers. It is useful when generating request forms, reviewing client operations, documenting an API integration, or checking query text safely before another tool attempts to execute it in production.
Extract declarations without confusing them with usages
GraphQL variables have two distinct appearances: a declaration such as <code>$id: ID!</code> beside an operation name, and one or more usages such as <code>user(id: $id)</code> inside the selection set. This capability reports declarations only. It groups them under the query, mutation, or subscription that owns them, so two operations can declare the same variable name without being merged. The returned type keeps the source notation that matters to callers: a scalar might be <code>String</code>, a required identifier might be <code>ID!</code>, and a required list of required identifiers might be <code>[ID!]!</code>. Default values and directives are parsed to establish that the surrounding document is syntactically sound, but they are not included in the result because the capability has one focused job: extracting variable names with their declared types. Fragments are parsed and validated as part of the document, although they cannot declare operation variables and therefore do not create output entries. An anonymous shorthand query is represented as a query operation without a name and with an empty variable list.
Use syntax checking as an early, deterministic guard
Extraction based on a regular expression can appear to work until a query contains comments, quoted strings, block strings, nested lists, object defaults, directives, fragments, aliases, or multiple operations. This parser tokenizes the complete document and follows the executable GraphQL grammar instead. It rejects unterminated strings, invalid number forms, unexpected characters, empty selection sets, malformed argument lists, broken variable definitions, and incomplete fragment or operation structures. That makes the result suitable for an automated build step: a successful response means the names and types came from declarations in a syntactically valid executable document, rather than from text that merely resembles GraphQL. The check is intentionally deterministic and makes no schema or network request. Consequently, it does not decide whether a field exists on your server, whether a variable type matches a particular argument, or whether an operation passes every schema-dependent validation rule. Those questions require the target schema. Use this capability for document syntax and declaration discovery, then use schema validation as a separate stage when a schema is available.
Integrate the structured result into developer tooling
The response contains an <code>operations</code> array in document order and a total <code>variable_count</code>. Each operation includes its operation kind, includes its name when one was written, and contains a <code>variables</code> array whose records have <code>name</code> and <code>type</code>. This stable shape works well for generating request editors, comparing checked-in operations, producing documentation tables, or detecting when a client query adds a new required input. Keeping operations separate is important in persisted-query collections and documents used by code generators, because a flat list loses ownership and can turn harmless repeated names into false conflicts. Inputs are limited to 200,000 characters so parsing remains bounded in both the browser and API runtime. No query is executed, no endpoint is contacted, and no schema, headers, credentials, or runtime variable values are required. Paste the GraphQL document into the browser runner for a local check, or call the API for $0.002 per item when extraction belongs in a repeatable pipeline. If the input is malformed, the request returns an invalid-input error with the approximate character position of the syntax problem.
What you can do with it
Build a variables form
Read operation declarations and create the correctly named inputs before collecting runtime values from a user.
Review persisted queries
Compare the declared names and exact GraphQL types when an operation changes in source control or a build artifact.
Document client operations
Turn a multi-operation GraphQL document into a concise inventory grouped by query, mutation, and subscription.
FAQ
Does this execute the GraphQL query?
No. It parses the document locally and never contacts a GraphQL endpoint.
Are variable usages included?
No. Only variables declared in an operation definition are returned; references inside fields, arguments, or directives are not separate declarations.
Does it preserve list and non-null type markers?
Yes. Types such as ID!, [String!], and [ID!]! are returned with their complete GraphQL notation.
Does it validate fields against my schema?
No. It validates executable-document syntax without a schema. Field existence and schema-dependent type compatibility require a separate schema validation step.
Can one document contain multiple operations and fragments?
Yes. Operations are returned in document order, while syntactically valid fragments are checked but do not add variable declarations.
What does the API call cost?
Each item costs $0.002. The browser version runs the same deterministic parser locally.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/graphql-query-variables-extract \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"}'const res = await fetch("https://api.kit.forhosting.com/dev/graphql-query-variables-extract", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"query": "query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/graphql-query-variables-extract",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"query": "query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/graphql-query-variables-extract", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"query":"query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"query":"query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/graphql-query-variables-extract", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"query": "query FindUser($id: ID!, $withPosts: Boolean = false) { user(id: $id) { name posts @include(if: $withPosts) { title } } }"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.graphql_query_variables_extract",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_chars | 200000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |