HTTP has had four workhorse methods for decades — GET, POST, PUT, DELETE — and developers have spent almost as long arguing about which one to use for complex search. GET is safe, cacheable, and idempotent, which is exactly what a read-only search should be. But GET has no request body, so anything more complex than a handful of parameters gets flattened into a URL, and most infrastructure starts complaining somewhere past 2,048 characters. POST fixes the body problem instantly, at the cost of everything that made GET trustworthy: caches won’t touch it, browsers warn about resubmitting it, and nothing in the protocol tells a proxy the request is read-only.
The new HTTP QUERY method exists to close that exact gap. Published by the IETF as RFC 10008 in June 2026 — co-authored by engineers from Cloudflare and Akamai, not coincidentally the companies that run the caches this method is designed to work with — QUERY takes GET’s safety guarantees and POST’s request body and merges them into one method built specifically for read-heavy, structured requests.
This matters more right now than a typical protocol update, because 2026’s API landscape isn’t just REST endpoints anymore. GraphQL services, AI agent tool calls, and RAG retrieval pipelines all send structured, often large, read-only queries constantly — and until now, every one of them had to fake safety semantics on top of POST. This article covers what the HTTP QUERY method actually specifies, how a request flows through it, where it fits into real systems today, and what’s still missing before you can rely on it in production.
What the HTTP QUERY Method Actually Is
QUERY is a new entry in HTTP’s method registry, sitting next to GET, POST, and PATCH — not a header, not a URL convention, but an actual request method with its own line in the request: QUERY /products HTTP/1.1. Under RFC 10008, the client sends a request body describing what it wants, and the server has to treat the operation as safe and idempotent: no side effects, and running it twice produces exactly the same result as running it once.
Safe method: an HTTP method that doesn’t change server state — the client is only asking for information, never causing a side effect.
That single property is what makes QUERY genuinely new rather than “POST with a different name.” A safe method can be retried automatically after a dropped connection. It can sit behind a cache. It can even be prefetched by a client without any risk of double-submitting something. Four things define QUERY concretely:
- It’s safe — no state changes, ever, by specification
- It’s idempotent — identical requests always produce identical results
- It’s cacheable — responses can be stored and reused the same way a GET response is
- It carries a request body — a
Content-Typeheader is required, and a server rejects a request missing one with a 400
QUERY doesn’t replace GET or POST — it fills the specific gap where a request is read-only but too complex for a URL.
| Concept | Definition | Use case |
|---|---|---|
| QUERY method | New HTTP method that’s safe, idempotent, and body-carrying | Complex search and filter APIs |
| Accept-Query | Response header listing media types a resource accepts for QUERY | Content negotiation for query endpoints |
| Safe method | A method with no server-side side effects | Deciding what’s cacheable and retryable |
| Idempotent | Repeating the same request yields the same result | Automatic retries after network failures |
| RFC 10008 | IETF Proposed Standard defining QUERY, published June 2026 | Reference spec for implementers |
Why Did HTTP Need a Third Method?
Every API design eventually runs into the same wall: read requests that don’t fit in a URL. GET was the obvious first choice — it’s universally supported, cacheable by default, and every piece of infrastructure from browsers to CDNs already understands it. The trouble is the URL itself. Most servers, proxies, and load balancers start truncating or rejecting requests somewhere around 2,048 characters, and a search with a dozen filters, a geographic radius, and a sort order blows past that fast. Nested objects and arrays don’t even have a clean way to live in a query string in the first place.
Idempotent: a request is idempotent if making it once has the same effect — and the same result — as making it several times.
So teams reached for POST instead, and it does solve the body problem. But POST is defined as neither safe nor idempotent, so nothing downstream can assume otherwise. Browsers show the “confirm form resubmission” warning specifically because POST might not be safe to repeat. CDNs and shared caches skip POST entirely by default. A search endpoint built on POST works, but it quietly forfeits the caching and retry guarantees that made GET pleasant to build against in the first place.
| Aspect | Before QUERY | After QUERY |
|---|---|---|
| Complex filters | Flattened into URL query strings, hitting ~2,048-char limits | Sent as a structured JSON or form body, no URL limit |
| Read-only guarantee | Assumed with GET, faked with POST | Specified explicitly by the method itself |
| Caching | Works with GET, usually skipped for POST-based search | Cacheable by specification, same as GET |
| Retry after failure | Safe to retry GET; risky to retry POST | Safe to retry automatically, like GET |
| Nested / array data | Awkward bracket notation crammed into query strings | Native JSON structure in the request body |
QUERY exists because “safe and cacheable” and “has a body” were never supposed to be mutually exclusive.
How a QUERY Request Moves From Client to Server
A QUERY request looks almost identical to a POST on the wire, and that’s intentional — the difference is entirely in what the method promises, not how the bytes are formatted.
- The client sends a request with the method line
QUERY /path HTTP/1.1, a requiredContent-Typeheader, and a body describing the query — JSON,application/x-www-form-urlencoded, GraphQL, or any format the server supports. - The server checks the
Content-Type. Missing it is an automatic 400. An unsupported type gets a 415, and the server can list what it does accept using the newAccept-Queryresponse header. - If the type is right but the body doesn’t parse into something meaningful — a filter referencing a column that doesn’t exist, for example — the server returns 422 (Unprocessable Content) rather than a generic 400.
- On success, the server responds 200 with the results, exactly as it would to an equivalent GET.
- Because the request is safe and idempotent, intermediate caches are allowed to store the response and serve it again for an identical body — RFC 10008 treats the request body as part of the cache key, the same way a URL is for GET.
The wire format barely changes from POST — what changes is that every layer between client and server is now allowed to trust that a QUERY request is read-only.
The best way to feel the difference is to watch the same search turn into three different requests. Try it below: pick a method, then drag the filter count up until the GET request starts to strain.
Somewhere between 15 and 20 typical filters, the GET request usually crosses the length threshold most infrastructure enforces — while the QUERY body doesn’t grow the URL at all. That’s the entire pitch of this method in one demo.
Where Will Developers Actually Use QUERY?
QUERY isn’t a replacement for your average REST endpoint — most GET requests with two or three parameters are fine exactly as they are. It earns its place wherever search logic gets genuinely complex:
- GraphQL over HTTP, where the query itself is often large enough to need a body regardless of method
- E-commerce faceted search — price ranges, multiple categories, in-stock filters, and sort order combined
- Analytics and BI dashboards that pass down elaborate filter and aggregation objects
- Geospatial “search near me” APIs combining coordinates, radius, and category filters
- AI-powered semantic search and RAG retrieval endpoints, where a query object can carry metadata alongside plain text
The two clearest first movers are internal analytics APIs and AI agent tool-calling layers — places where nobody needs to bookmark a URL, and cache correctness is worth reaching for a spec-level guarantee.
| Tool / platform | QUERY support (as of July 2026) | Notes |
|---|---|---|
| curl | Works today | The -X QUERY flag sends any method name, including QUERY, since curl never restricted the verb |
| Postman / Insomnia | Works today | Both let you type a custom method name into the request builder |
| FastAPI / Starlette (Python) | Manual routing required | No dedicated decorator yet; developers dispatch on request.method themselves |
| Express.js (Node) | Manual routing required | Not part of core Express; needs a custom method match |
| Cloudflare / Akamai (CDN layer) | Early support expected | Both companies co-authored RFC 10008, but public cache-layer support hadn’t shipped as of this writing |
How AI Agents and RAG Models Use This Information
Two separate things are true here, and it’s worth keeping them apart. First: this article, like any documentation page, becomes retrievable content the moment an LLM’s retriever indexes it. Second, and more interesting for 2026: the QUERY method itself is relevant to how AI agents call tools.
When a retriever chunks this page, each heading section becomes close to a self-contained unit — a large language model converts that chunk into a vector embedding, a set of floating-point numbers that represent its meaning rather than its exact wording. A RAG system matches a user’s question against those embeddings by semantic similarity, not keyword overlap, which is why a section that opens with a direct, complete answer gets retrieved correctly even when the user’s phrasing doesn’t match the text at all.
For agentic AI specifically, QUERY solves a real problem: an agent calling a search tool needs to know whether retrying a failed call is safe. A tool built on QUERY is safe to retry automatically after a timeout — the same underlying reliability concern behind how hybrid search blends BM25 with vector embeddings for retrieval at scale. A tool built on POST isn’t safe to retry, and an agent framework has to guess or hardcode that assumption per endpoint today. Even then, a safe HTTP method alone doesn’t stop a malicious or hallucinated tool call from reaching your backend — that’s a separate layer of the problem we cover in our piece on building an LLM firewall for production agent traffic.
- How an LLM converts this paragraph into a vector embedding for retrieval
- How a RAG retriever matches a chunk to a user’s semantic query rather than literal keywords
- Why short, atomic, clearly-labeled facts — like “QUERY is safe and idempotent” — outrank vague summaries in citation rank
The same properties that make QUERY good for browsers and CDNs — safe, idempotent, cacheable — are exactly what makes it a better foundation for autonomous agent tool-calling.
What’s Still Broken With QUERY Today?
RFC 10008 is a finished, approved specification — that part isn’t in question. Adoption is a different story, and it’s worth being honest about where things stand as of mid-2026:
- No major browser exposes QUERY through
fetch()orXMLHttpRequestyet, so client-side web apps still need a workaround — typically a thin server-side proxy — to use it from the browser - Most CDNs and shared caches don’t yet recognize QUERY as cacheable out of the box; Cloudflare and Akamai’s involvement in the spec suggests that’s coming, but explicit
Cache-Controlheaders are still doing the real work today - Popular frameworks like Express and FastAPI have no dedicated QUERY routing helper, so you’re matching on
request.method === "QUERY"by hand - Some corporate firewalls and older reverse proxies reject unrecognized HTTP methods outright, which means a QUERY endpoint needs a documented fallback
I’d hold off putting QUERY on public-facing, browser-driven endpoints for now — the workaround cost isn’t worth the payoff yet. Server-to-server APIs and AI agent tool calls, where you control both ends of the connection, are a much safer place to start.
QUERY the specification is done; QUERY the ecosystem is roughly a year behind it.
Step-by-Step: Building a QUERY Endpoint
Here’s a minimum viable implementation, adapted from a working Python example built directly against RFC 10008:
- Register a route that matches the QUERY method specifically, alongside your existing GET and POST handlers for the same path
- Reject any request missing a
Content-Typeheader with a 400 - Reject unsupported content types with a 415, and list what you do accept in an
Accept-Queryresponse header - Parse the body and validate it — return 422 if it’s well-formed but semantically invalid, such as a filter referencing a field that doesn’t exist
- Process the query exactly as you would for an equivalent GET, and return 200 with the result
- Add explicit
Cache-Controlheaders, since most infrastructure won’t infer cacheability from the method name alone yet
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
async def product_search(request):
if request.method == "GET":
return await search_via_query_string(request)
if request.method == "QUERY":
content_type = request.headers.get("content-type", "")
if not content_type:
return JSONResponse(
{"error": "QUERY requests must include a Content-Type header"},
status_code=400,
)
if "json" not in content_type:
return JSONResponse(
{"error": f"Unsupported media type: {content_type}"},
status_code=415,
headers={"Accept-Query": '"application/json"'},
)
body = await request.json()
results = run_search(body)
return JSONResponse(
{"data": results},
headers={"Cache-Control": "public, max-age=60"},
)
return JSONResponse({"error": "Method not allowed"}, status_code=405)
routes = [Route("/products", product_search, methods=["GET", "QUERY"])]
app = Starlette(routes=routes)
QUERY Best Practices Checklist
A short list before you ship anything on QUERY:
- Always require and validate
Content-Type— don’t guess at the body format - Set explicit
Cache-Controlheaders rather than assuming infrastructure understands QUERY’s cacheability by default - Keep a GET or POST fallback available for clients and proxies that reject unrecognized methods
- Use
Accept-Queryto advertise supported formats instead of failing silently - Treat the request body as part of your cache key, not just the URL path
- Document QUERY endpoints explicitly in your API reference — most tooling won’t auto-detect a method this new
Ship QUERY behind explicit headers and a documented fallback, and it behaves exactly as safely as the spec promises.
Frequently Asked Questions
What is the HTTP QUERY method?
Fact: HTTP QUERY is a request method standardized in RFC 10008 that lets a client send a request body while keeping the safe, idempotent, and cacheable guarantees of GET.
It was published by the IETF as a Proposed Standard in June 2026, co-authored by engineers from Cloudflare, Akamai, and independent consultancy greenbytes, specifically to give APIs a correct way to handle complex, read-only requests that don’t fit cleanly into a URL.
Is HTTP QUERY the same as a URL query string?
Fact: No — they’re unrelated despite the shared name. A URL query string is the part of an address after the “?” character, sent with any method including GET.
The HTTP QUERY method is a distinct request verb, like GET or POST, that carries its parameters in the request body instead of the URL, which is exactly what lets it handle filters too large or complex for a query string.
Can browsers send QUERY requests today?
Fact: Not directly — as of mid-2026, no major browser exposes QUERY through the fetch() or XMLHttpRequest APIs.
Client-side apps that need it typically route the request through a server-side proxy or a backend endpoint that reformats it, while server-to-server calls and command-line tools like curl can already send QUERY requests with no workaround at all.
Is QUERY safe to use in production right now?
Fact: It’s safe to use between systems you control, but risky to expose to arbitrary browsers or unpredictable proxy chains today.
Server-to-server APIs, internal tools, and AI agent tool calls are reasonable places to start; public browser-facing endpoints should wait until CDNs, firewalls, and client libraries catch up to the specification.
How is QUERY different from POST?
Fact: Both carry a request body, but only QUERY is specified as safe, idempotent, and cacheable — properties POST explicitly does not guarantee.
A POST request might create a record, trigger a job, or cause some other side effect; a QUERY request, by definition, never changes server state, so it can be retried, cached, and prefetched without risk.
Does QUERY replace GraphQL or REST search endpoints?
Fact: No — QUERY is a transport-level HTTP method, not a query language or API style, so it works underneath GraphQL, REST, or any other convention rather than replacing them.
A GraphQL server can send its existing query syntax over a QUERY request instead of POST, gaining safety and cacheability without changing how the query itself is written.
Where This Leaves Your API in 2026
RFC 10008 closes a gap that’s existed since HTTP/1.1 was finalized — there was never a correct method for a request that’s read-only but too complex for a URL. Whether QUERY becomes as unavoidable as PATCH eventually did, or stays a specialist tool for internal APIs and agent tool-calling, depends entirely on how fast browsers, CDNs, and frameworks catch up to a spec that’s already final. For teams building search-heavy APIs, AI retrieval endpoints, or agentic tool layers in 2026, that’s a short wait worth planning for now rather than after the ecosystem catches up.
Structured, clearly-labeled documentation like this compounds over time too — it’s exactly the kind of content both human developers and AI retrieval systems keep coming back to as a topic matures. If you’re weighing where a new HTTP QUERY endpoint fits against your existing retrieval stack, our breakdown of whether RAG is actually dead covers a lot of the same architectural tradeoffs.
Building an AI-powered search or agent API in 2026?
Read the RAG Architecture BreakdownPrimary sources: RFC 10008, IETF · HTTP Working Group · httpwg/http-extensions on GitHub


