HTTP QUERY: A new HTTP method, 11 years in the making

17 juni 2026

It's finally here! The QUERY method. After over a decade of work, the IETF has finally published RFC 10008, a new HTTP method that fills a gap developers have been working around for years. The first draft was submitted back in April 2015 under the name SEARCH. The name was later changed to QUERY (partly because SEARCH already exists as an HTTP method from WebDAV), and after 14 revisions and 11 years it finally crossed the finish line.

What is it?

QUERY is a new HTTP method designed for sending a query to a server with a request body. Like GET it is safe and idempotent, meaning it does not change the state of the target resource and you can safely retry it. Unlike GET, it has well-defined semantics for a request body.

A simple example:

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/json
Accept: application/json

{
  "select": ["surname", "givenname", "email"],
  "limit": 10,
  "match": "email=*@example.*"
}

The server processes the query and returns matching results directly in the response body.

Why do we need it?

HTTP GET is great for fetching resources but it has a fundamental limitation: the query lives in the URL. That works fine for simple cases but breaks down when:

  • The query is too large to fit in a URL. There is no hard limit in the spec, but many servers, proxies and clients cap it.
  • The query format is complex; expressing structured data like SQL or JSONPath as URL-encoded query parameters is ugly and error-prone.
  • URLs get logged everywhere, in load balancers, proxies, access logs, browser history, bookmarks. This means that sensitive query data ends up places you don't want it.

Why not just use POST?

This is the obvious question, and the honest answer is that people have been using POST for this for years. But POST has a semantic problem; it is neither safe nor idempotent. That matters for several reasons:

  • Caches rarely cache it. A POST response can only be used to satisfy future GET or HEAD requests to the same URI. A QUERY response can be cached and reused for identical QUERY requests. (Note: While it is semantically cacheable, it will take time for CDNs and caching infrastructure to practically support caching based on request bodies, as they currently rely heavily on URLs and headers for cache keys).
  • Clients won't retry it automatically. If a connection drops mid-request, HTTP clients and intermediaries know they can safely retry a GET or QUERY. They cannot safely retry a POST because it might have side effects.
  • It's not self-documenting. When you see POST /search, you have to know the API to understand it's a read-only operation. QUERY /search makes the intent explicit at the protocol level.

Location and Content-Location

One of the more interesting features of QUERY is how the server can optionally assign URIs to query results or to the query itself. Both of these headers are optional but can in some cases improve performance and cacheability.

Content-Location in the response points to a URI where this specific result can be retrieved later with a plain GET:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Location: /contacts/stored-results/17

Location in the response points to a URI representing the query itself, a stored query that, when fetched with GET, re-runs the query and returns the result at that point in time:

HTTP/1.1 200 OK
Content-Type: application/json
Location: /contacts/stored-queries/42

The difference: Content-Location gives you back the frozen result from this execution. Location gives you a bookmark to run the same query again later. Both are optional, and a server that doesn't want to store anything just returns the result and that's that.

What now?

The RFC was published on June 16, 2026 and there are already working implementations.

  • The Rust HTTP primitives library hyperium/http merged support on the same day, which means reqwest and axum will pick it up automatically on their next releases.
  • axum has an open issue tracking the routing support needed on top of that.
  • Apache HttpComponents (Java) had experimental support already during the draft phase and has an open PR to remove the @Experimental tag.
  • Netty opened a PR for HttpMethod.QUERY the day after publication.
  • Frameworks and clients that accept arbitrary method strings like Go, Python, Node.js and curl already work with QUERY without code changes. .NET and Spring have no open issues at the time of writing. What's missing there is named constants and first-class routing support.
  • The major reverse proxies (nginx, HAProxy, Traefik, Caddy, Apache httpd, Envoy) all pass QUERY requests through without blocking.
  • There's an open issue in the WHATWG Fetch spec from 2024 to add QUERY to the CORS safelisted method list, but it remains unresolved.

In other words: server-to-server use cases are close to usable today, but widespread browser adoption will take longer. Frontend developers can use fetch('...', { method: 'QUERY' }) today, but because it is not yet a CORS-safelisted method, browsers will always trigger an OPTIONS preflight request. This means the backend must explicitly include QUERY in its Access-Control-Allow-Methods response header, otherwise the browser will block the request.

QUERY won't replace GET or POST and that's not the point. It gives us something we've been missing: a standard way to express safe, idempotent, body-based queries without overloading semantics. If you build APIs, this is a good time to start experimenting in server-to-server scenarios, add QUERY to your allow-lists, and verify your cache and retry behavior. Browser tooling and framework ergonomics will catch up, but the protocol building block is finally here.