If you've built APIs for any length of time, you've almost certainly hit this wall: you need to fetch data based on a complicated set of filters, but GET can't carry a body, and cramming a nested filter object into a query string turns into an unreadable, size-limited mess. So you reach for POST instead — and now your "read" operation looks like a "write" to every cache, proxy, and retry mechanism between your client and your server.
That mismatch has existed since the early days of HTTP. As of June 2026, it doesn't have to anymore.
The IETF has published RFC 10008: The HTTP QUERY Method as a Proposed Standard — the first genuinely new, general-purpose HTTP method to reach standardization in years. It was authored by Julian Reschke, James M. Snell (Cloudflare), and Mike Bishop (Akamai), and it gives the web a method that behaves like GET in terms of safety and cacheability, while carrying a request body like POST.
The problem QUERY was built to solve
HTTP developers have historically had exactly two tools for "give me data based on these parameters," and neither one is quite right.
GET puts everything in the URI. That's semantically clean — the resource is fully identified by the URL, so caching, bookmarking, and safe retries all just work. But it falls apart once your query gets complex:
- There's no reliable, agreed-upon size limit. A request might pass through several intermediaries that each impose their own cap, and RFC 9110 only recommends 8,000 octets as a rough floor — not a guarantee.
- Structured data — nested filters, arbitrary JSON — is awkward and expensive to squeeze into a URL-safe string. Anyone who's base64-encoded a JSON blob into a query parameter knows the pain.
- URIs get logged, cached by browsers, and passed around far more casually than request bodies do, which becomes a real problem the moment your query includes anything sensitive.
- Every distinct set of parameters is technically a distinct resource, which is rarely what you actually mean semantically.
POST solves the size and encoding problems, since the payload lives in the body instead of the URL. But it throws away the one property that made GET useful: nothing in HTTP's method semantics tells a cache, proxy, or client whether a given POST is safe to retry or safe to cache. Some POST endpoints mutate state, some don't — and HTTP itself can't tell the difference, so every intermediary has to assume the worst.
The workaround many APIs settled on — a GET/POST/GET dance to search, materialize a result resource, then fetch it — was really just people improvising a method that HTTP didn't have.
What QUERY actually does
QUERY takes the request semantics of GET and pairs them with the request-body mechanics of POST. Here's the comparison at a glance:
| GET | QUERY | POST | |
|---|---|---|---|
| Safe | Yes | Yes | Not guaranteed |
| Idempotent | Yes | Yes | Not guaranteed |
| Query lives in the URI | Yes, by definition | Optional | No |
| Cacheable | Yes | Yes | Only for a subsequent GET/HEAD |
| Request body | No defined semantics | Expected | Expected |
A QUERY request targets a resource (via the URI, same as GET) and encloses content describing how that resource should be queried — arbitrary JSON, SQL, GraphQL, XML, whatever the server is willing to accept. The server processes that content safely and idempotently, then returns the result.
Because QUERY is registered in the IANA HTTP Method Registry as both safe and idempotent, this isn't something you have to document in your API reference and hope people read — any generic HTTP client, proxy, or cache can treat QUERY requests correctly without knowing anything specific about your API. Retrying a QUERY after a network hiccup is always safe, exactly like retrying a GET.
A basic QUERY request
QUERY /products HTTP/1.1
Host: shop.example.com
Content-Type: application/json
Accept: application/json
{
"filter": {
"category": "electronics",
"price": { "lt": 500 },
"inStock": true
},
"sort": "-rating",
"limit": 20
}
The server responds the same way it would to any successful GET — a 200 OK with the representation the client asked for.
Accept-Query: telling clients what you speak
Since a QUERY body's meaning depends entirely on its Content-Type — unlike WebDAV's older safe-body methods (PROPFIND, REPORT, SEARCH), which are all tied to a single XML media type — a server needs a way to advertise which query languages it actually understands. That's what the new Accept-Query response header is for:
Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
A client can send a HEAD or OPTIONS request first, read Accept-Query, and pick a format the server supports — instead of guessing and getting back a 415 Unsupported Media Type.
Location vs. Content-Location: don't mix these up
RFC 10008 introduces the idea of an "equivalent resource" — a conceptual resource derived from the target URI plus the request content. A server can expose that resource through two different headers, and confusing them is the most common mistake teams are likely to make:
-
Content-Locationpoints to a snapshot of this specific result. It's useful for caching the answer to a query that already happened. -
Locationpoints to a URI the client canGETlater to repeat this exact query without resending the body. It turns an expensiveQUERYinto a cheap, cacheableGETfor next time.
Mix these up and your caching layer will start serving stale results or the wrong data entirely — Content-Location is a snapshot, Location is a live, repeatable query.
Caching a body is harder than caching a URL
This is the part of the spec worth reading twice if you run a CDN or reverse proxy. A QUERY response is cacheable, but the cache key has to incorporate the entire normalized request body, not just the URI. That means a cache has to read and normalize the whole payload before it can even check for a hit — normalizing away things like content-encoding differences or JSON key ordering, but only in ways that don't change how the server actually interprets the query. Get the normalization wrong and you'll get false-positive cache hits, which the spec's Security Considerations section calls out explicitly as a real risk, not a theoretical one.
The catch: CORS preflights
If you're calling a QUERY endpoint from browser JavaScript, there's one thing to plan for: QUERY is not on the CORS-safelisted method list. Every cross-origin QUERY call will trigger an OPTIONS preflight first, exactly like a POST with a non-simple Content-Type already does today. It's rarely a reason to avoid QUERY, but it is a reason not to be surprised when your network waterfall grows an extra round trip on hot paths.
Where things stand today
Publishing a Proposed Standard doesn't mean the whole ecosystem wakes up supporting it the next morning. As of mid-2026:
-
No major browser implements
QUERYnatively yet. You can't currently send it fromfetch()orXMLHttpRequest— this has been an open, actively discussed request against browser fetch implementations, since browsers generally allow arbitrary method names but the ergonomics for a genuinely new safe method with a body still need to be worked out across engines. -
Server frameworks are catching up faster. Runtimes and languages that let you match arbitrary method strings — Go's
net/httpwith its 1.22+ method-aware routing, for instance — can supportQUERYtoday with no changes needed, since the method name is just a string to them. Node.js'shttpmodule has had community interest and active discussion around first-class support for the method as well. -
.NET 10 (LTS, released November 2025) is among the first major platforms to ship built-in
QUERYsupport on both the client and server side, including a dedicatedHttpMethod.Queryon the client. - Proxies and CDNs don't yet cache
QUERYresponses at scale by default — though the fact that two of the RFC's three authors work at Cloudflare and Akamai is a fairly strong signal about where that's headed.
A sane way to roll it out
Given where adoption stands, treat QUERY as an addition, not a replacement — at least for now:
- Keep your existing
POST-based search or filter endpoint in place. - Add a
QUERYhandler alongside it that accepts the same content shape. - Advertise supported query formats via
Accept-Query. - Let clients migrate to
QUERYas their tooling — SDKs, browsers, corporate proxies with method allow-lists — catches up.
That gives you the correct semantics for the clients that already understand QUERY, without breaking anything for the ones that don't.
Why this matters
QUERY isn't a flashy addition — it's a plumbing fix. It closes a hole in HTTP's method vocabulary that's been there since the protocol's earliest days, and it does it in a way that's mechanically enforceable by generic infrastructure rather than something you have to explain in your API docs and hope developers respect. If you maintain an API with a search or filter endpoint that outgrew GET years ago and settled uneasily into POST, this is the method that endpoint always should have had.
It'll take time for browsers, proxies, and client libraries to fully catch up. But for server-side APIs, service-to-service calls, and any client stack that already supports arbitrary HTTP methods, there's nothing stopping you from adding QUERY support today.
Further reading: RFC 10008 — The HTTP QUERY Method at the RFC Editor.
Top comments (0)