ResourceRFC 10008 · June 2026

RFC 10008: The HTTP QUERY Method

The problem QUERY solves

HTTP has always had a bit of a problem. On one hand, a GET request is safe, idempotent, and cacheable, which is exactly the properties you want for a read-only lookup. The issue is that is has no defined semantics for a request body, so any parameters have to be squeezed into the URI as a query string. This could become a problem as parameters got added and there was a risk that a URI could breach their limitations. A POST request can carry a body of any size and shape, but it isn't safe or idempotent, so nothing in the chain i.e browsers, proxies, CDNs, caches is allowed to retry or cache it automatically.

That's fine for a simple filter, but it breaks down once a query gets complex: think a search endpoint with dozens of filters, a GraphQL-style query document, or a geospatial lookup with nested parameters. Cramming that into a URL runs into real problems:

  • Size limits are uncoordinated. A request URI passes through servers, proxies, and CDNs that each enforce their own undocumented length limit.
  • Encoding is wasteful. Structured, nested data has to be flattened and percent-encoded to survive in a URI, which is inefficient and easy to get wrong.
  • URIs leak more than bodies. URIs are far more likely to end up in access logs, browser history, and referrer headers than a request body which could be a real problem if the query contains sensitive filters.
  • It conflates queries with resources. Encoding a query in the URI implies every distinct combination of parameters is its own resource, when it's really the same search being sliced differently.

QUERY (RFC 10008, published June 2026 by Julian Reschke, James M. Snell, and Mike Bishop under the IETF httpbis working group) closes that gap: a method that behaves like GET for caching, retries, and side effects, but carries its parameters in the body like POST.

QUERY METHOD overview

SafeNo side effectsQUERY must not modify the state of the target resource (though a server may create incidental resources to hold the result).
IdempotentSafe to retryClients and intermediaries can automatically repeat a QUERY after a dropped connection without worrying about partial state changes.
CacheableFollows HTTP cachingResponses can be cached per normal HTTP rules, but the cache key must incorporate the request body. Caches may normalise insignificant differences like key order or content encoding.
Has a bodyContent-Type requiredA server must reject a QUERY with no Content-Type, or with inconsistent metadata, with a 4xx response.

Error handling gets two specific status codes worth knowing: 415 Unsupported Media Type when the server doesn't understand the query format, and 422 Unprocessable Content when the query is syntactically valid but fails on its merits e.g. a SQL query referencing a table that doesn't exist.

Accept-Query: discovering support

RFC 10008 introduces a response header, Accept-Query, that lets a server advertise which query formats an endpoint understands, using HTTP Structured Fields syntax:

Example response headerAccept-Query: "application/jsonpath", application/sql;charset="UTF-8"

The header applies to every URI sharing the same path and the query component of the URI is ignored, so a client can discover what a resource accepts before constructing a request.

Where it sits among the HTTP methods

The clearest way to see what QUERY adds is to line it up against the methods you already test against. It sits exactly between GET and POST: GET's guarantees, POST's payload.

MethodSafeIdempotentRequest bodyCacheableTypical use
GETYesYesNo defined semanticsYesRetrieve a resource
HEADYesYesNoYesRetrieve headers only
OPTIONSYesYesNoNoDiscover allowed methods / CORS preflight
QUERYYesYesExpectedYes (cache key includes body)Large or complex read-only queries
POSTNoNot guaranteedYesOnly if explicitly markedCreate a resource / non-idempotent actions
PUTNoYesYesNoReplace a resource entirely
PATCHNoNot guaranteedYesNoPartially update a resource
DELETENoYesOptionalNoRemove a resource

A few other details round out how QUERY behaves at the protocol level: 301 and 308 redirects preserve the method (like GET, unlike POST), a 303 signals that the same result is available via a plain GET, and conditional headers like If-Modified-Since work the same way they would against an equivalent GET. Servers can also expose a Content-Location (for the result) or Location (for the query itself) so a client can fetch the same thing again with a cheap GET instead of resending the whole query body.

What this means for testing

A few things are worth building into your test approach before QUERY shows up in an API you're testing:

  • CORS preflight is mandatory. QUERY isn't on the CORS-safelisted method list, so unlike a simple GET, a cross-origin QUERY will trigger an OPTIONS preflight so it's definitely worth checking that preflight responses are configured correctly.
  • Cache poisoning has a new angle. Since the cache key includes the request body, test that two different bodies to the same URI don't collide in cache, and that caches don't serve a stale result for a body they've normalised.
  • Idempotency claims need verifying, not assuming. Just because a QUERY endpoint is supposed to be safe doesn't mean the implementation behind it is, treat that guarantee the same way you'd treat any other claim.