HTTP QUERY (RFC 10008): a safe method with a body for complex searches - init.d
IT

# HTTP QUERY (RFC 10008): a safe method with a body for complex searches

Alessandro Corbelli~7 min read min
Table of Contents

Anyone who works with web APIs knows the recurring annoyance. When a search gets complex - many filters, lists of values, nested conditions - there’s no genuinely clean way to express it with the HTTP methods we’ve always had. In June 2026 the IETF, the body that maintains Internet’s technical standards, published RFC 10008 and introduced a new HTTP method built for exactly this case. It’s called QUERY.

The problem QUERY sets out to solve

Every HTTP request has a “method”: a verb that tells the server what you want to do. The best-known ones are GET (read something) and POST (send data, usually to create or change something).

Anyone designing a search API runs into an uncomfortable fork in the road:

  • GET is the right method for reading, but its parameters travel in the query string - the tail of the address after the question mark (?name=value&...). Addresses, however, have practical length limits: servers, proxies and browsers can truncate or reject overly long URLs. On top of that, the address almost always ends up in logs and in history. Expressing an elaborate filter in a query string quickly becomes unreadable and brittle.

  • POST lets you attach a body - the part of the message where the actual data goes, in JSON or other formats. Many APIs use POST for searches purely to get access to that body. The catch is that POST was designed for operations that change something, and that confuses everything sitting in the middle.

Two terms help here, in plain words. A request is safe when it’s read-only: nothing on the server is expected to change. A request is idempotent when repeating it unchanged doesn’t alter the outcome: sending it once or ten times leaves the same state. GET has both properties; POST does not. That’s why caches and proxies can’t automatically retry a POST after a network error, nor comfortably store its response: they don’t know whether that request “touched” anything.

The upshot is a choice between two compromises: a clean GET with a query string that bursts at the seams, or a convenient POST that is semantically wrong for a plain search.

What the QUERY method is

QUERY fills precisely this gap. RFC 10008 describes it as a safe, idempotent request that carries content describing how the target resource should process it, with the resource then responding with the result of that processing.

In practice: it’s a read-only request like GET, but with a body like POST. The standard is blunt about the two properties. On safety, the client “does not request or expect any change to the state of the target resource”. On idempotency, QUERY requests “are idempotent; they can be retried or repeated when needed, for instance, after a connection failure”.

Put differently, QUERY gives API designers the thing that neither GET nor POST offers on its own: a complex search, with a structured body, that stays repeatable and cacheable without risk.

GET, POST and QUERY side by side

A simple way to pin down the idea:

  • GET - reads, with no useful body; parameters live in the URL, with its limits.
  • POST - has a body, but is neither safe nor idempotent: meant to change things.
  • QUERY - has a body and is safe and idempotent: meant to interrogate.

The difference isn’t cosmetic. It makes the real intent - “I’m only reading” - explicit to the server, to caches and to proxies, and it unlocks behaviours like automatic retry and cache storage that would be reckless with POST.

How it works, concretely

A few details from the standard make its use clearer.

The content type is mandatory. A QUERY body can be in any format: JSON, an SQL-like expression, a proprietary filter language. Precisely because of that, the server needs to know what it’s receiving. The RFC requires the server to fail the request if the Content-Type header is missing or inconsistent with the content, and it forbids “guessing” the format from the data (no content sniffing). A request with no media type is rejected with a 4xx status, typically 400.

There’s a way to advertise support. The standard introduces a new response header, Accept-Query, with which a resource can declare that it accepts QUERY and which query formats it understands. An example from the specification: Accept-Query: "application/jsonpath", application/sql;charset="UTF-8". It gives clients an orderly way to discover that the option is available.

Responses can be cached. This is the most tangible practical benefit, because it directly affects the response time users feel. A QUERY response is cacheable, with one caveat: the cache key - the identifier used to find the response again - must take the request body and its metadata into account, not just the URL. Caches may normalise insignificant differences in the content to recognise equivalent requests, but only for the purpose of the key, without altering the actual request.

The response can point to where the result lives. The server can include a Content-Location header pointing to a resource that holds the result of the operation (possibly temporary), or a Location header naming an “equivalent” resource: an address the client can later hit with a plain GET to repeat the same query without resending the whole body.

Security and compatibility: what to watch

There are practical points worth weighing before adopting it.

On privacy there’s a clear benefit: moving the search criteria from the URL into the body keeps sensitive data out of logs more often, because - as the RFC notes - the address is logged and processed by intermediaries far more than the content is. The standard also recommends that, if the server creates a temporary resource for the result, the assigned address shouldn’t contain sensitive parts of the original query.

Adoption friction remains, though. In browsers, a cross-origin QUERY requires a CORS preflight - a preliminary check the browser performs to verify permissions - because QUERY isn’t among the methods treated as “safe by default”. It’s also worth remembering that the exception whereby a redirect turns a POST into a GET (301 or 302 responses) does not apply to QUERY. And, plainly, every link in the chain - proxies, web servers, frameworks, client libraries - has to learn to recognise the new method: until it does, a QUERY can be blocked or mishandled.

Where standardisation stands

A clarification is needed here, because the old wording is still floating around. For years this proposal existed as an Internet-Draft named draft-ietf-httpbis-safe-method-w-body, developed by the IETF’s httpbis working group, the same one behind the header that flags deprecated APIs and the concealed authentication scheme. In November 2025 the text was approved, and in June 2026 it was published as RFC 10008. So it’s no longer a mere draft: it’s a published document.

Mind the maturity level, though. RFC 10008 is a Proposed Standard, the first stable rung on the IETF standards track: a mature text, publicly reviewed and citable, but not yet the final “Internet Standard” level. In practical terms the specification is solid, while real support across servers, proxies and frameworks is still spreading.

The authors are Julian Reschke (greenbytes), James M. Snell (Cloudflare) and Mike Bishop (Akamai). The presence of Cloudflare and Akamai, two large network and CDN operators, is a useful signal: they are exactly the players who need to support the method along the path for it to become usable at scale, the same push behind Cloudflare’s experiments on other fronts of the protocol, such as a new use of the HTTP 402 status for AI crawler traffic.

Why it can help API developers

QUERY’s value isn’t yet another acronym; it’s giving a correct name to something people were already doing by bending their tools. Those who have used POST for searches did so for a legitimate technical reason - they needed a body - but paid for it in clarity and lost caching and automatic retry.

Looking ahead, for an API with elaborate searches it’s worth considering QUERY as the more honest alternative: it keeps read semantics, sidesteps URL limits, keeps criteria out of the logs and reopens the door to caching. In the meantime, since adoption across the chain isn’t universal yet, a prudent approach is to keep a POST fallback and to check how proxies and clients behave before relying on QUERY alone in production. It’s one of those changes that won’t upend everything tomorrow, but that over a few years can reasonably be expected as a standard option in search APIs.

Sources

Tux versione Gandalf, mascotte del blog init.d

init.d is the team led by Alessandro Corbelli, a Linux systems administrator and backend developer with over twenty years of experience. He designs and runs cloud infrastructure (Google Cloud, AWS, Azure), server farms and high-availability architectures, and builds custom software in Laravel/PHP and Vue - from the Take2Me food delivery platform to our clients’ management tools. On this blog we share technical notes on Linux, system administration, development, DevOps and e-commerce.


More Posts