TWISTEdBRACKETS

RFC 10008: HTTP Finally Gets a Query Method

Published

3 July 2026

Listen to this post using the player at the bottom of the page.

In June 2026 the IETF published RFC 10008, standardising a new HTTP method called QUERY. If you have ever built a search API, run GraphQL over POST, or watched a URL grow to four thousand characters because someone added one more filter, this one is for you.

HTTP has had GET and POST since the early 1990s. PATCH arrived in 2010. DELETE and PUT have been around for decades. QUERY is the first genuinely new general-purpose read method in a long time, and it closes a gap the web has been papering over since roughly 1999.

A quick history of how we got here

GET and POST were defined in HTTP/1.1 (RFC 2616, 1999). GET retrieves a representation of a resource. POST submits data for processing, usually changing something. That split made sense when the web was mostly documents and form submissions.

The problem is that "retrieve" and "search" are not the same thing. GET assumes your inputs fit in the URI. POST assumes you might be mutating state. Neither was designed for "run this complex read-only operation and give me the results."

Developers noticed early. By the late 2000s, WebDAV had already tried to fix this with the SEARCH method (RFC 5323, 2008), authored in part by Julian Reschke, who also led RFC 10008. SEARCH was safe and idempotent, but it lived inside the WebDAV world, tied to XML, and never broke out into mainstream API design.

Meanwhile everyone else improvised. GraphQL servers accept POST. Elasticsearch, Solr, and countless REST APIs expose POST /search endpoints. SQL-over-HTTP experiments send query bodies through POST because there is nowhere else to put them. It works. It is also a workaround, not a standard.

Discussion on a proper solution reopened at the HTTP Workshop in 2019, when Asbjørn Ulsberg raised the issue again. The early drafts used the name SEARCH before the working group settled on QUERY: clearer semantics, no WebDAV baggage, and a natural link to the URI query component the method is meant to replace.

Seven years of drafts later, RFC 10008 landed as a Proposed Standard. Reschke, James M. Snell (Cloudflare), and Mike Bishop (Akamai) are the authors. IANA has registered QUERY in the HTTP Method Registry. The spec is done. The ecosystem is not.

HTTP methods for read operations
GET fits simple lookups. POST became the de facto workaround. QUERY is designed for the middle ground.

Why GET breaks down for real queries

GET is brilliant for what it was built for. Fetch this page. Load this image. Retrieve a resource identified by a URI.

Put a non-trivial search into that URI and things get awkward fast.

Size limits. HTTP recommends supporting URIs of at least 8,000 octets, but a request can pass through proxies, load balancers, and logging systems with their own limits. Nobody knows the smallest ceiling on the path. Complex filters, GraphQL operations, and JSON query objects blow past practical limits quickly.

Encoding overhead. Structured data in a query string is verbose and ugly. Nested objects become percent-encoded soup. Every filter parameter is another & on the wire.

Visibility. URIs show up in server logs, browser history, and analytics dashboards. Sometimes that is fine. Sometimes your query contains PII or internal identifiers you would rather keep out of the access log.

No body semantics. RFC 9110 (the current HTTP semantics document) says a payload on a GET has "no defined semantics." Some clients send one anyway. Some servers reject them. Intermediaries may strip the body. You cannot build a reliable standard on "maybe it works."

So teams encode everything in the URL until they cannot, then reach for POST.

Why POST is the wrong tool

POST is not evil. It is just the wrong default for read-only operations.

POST is not safe. A safe method should not change server state. POST might create a record, charge a card, or enqueue a job. Intermediaries and clients treat it that way.

POST is not idempotent. Send it twice and you might get two side effects. Automatic retries, which every resilient client needs, become dangerous.

Caching suffers. HTTP caching can store POST responses, but only for future GET or HEAD requests to the same URI. That is a narrow, awkward path. CDNs and browser caches are built around GET. A POST search result does not get the same treatment as a GET resource.

Redirects are messy. A 301 or 302 redirect after POST often becomes a GET at the new location. That made sense for form submissions in 1999. It is wrong for a search you wanted to repeat verbatim.

The result is a silent contract: "trust us, this POST does not actually mutate anything." Some APIs document that clearly. Many do not. Proxies, caches, and generic HTTP tooling cannot tell the difference without out-of-band knowledge of your application.

That is the gap QUERY fills.

What QUERY actually gives you

QUERY sends query input in the request body, like POST. Unlike POST, it is explicitly safe and idempotent.

You can retry a failed QUERY without worrying you just submitted an order twice. Intermediaries can treat it as a read. Caches can store responses, with the cache key incorporating the request body and its Content-Type, not just the URI.

A few practical details from the spec:

  • Content-Type is required. The server must reject requests without it or with inconsistent content. No sniffing.
  • Accept-Query response header tells clients which query formats a resource supports (JSONPath, SQL, form data, whatever the server implements).
  • Location and Content-Location let the server hand back a GET-able URI for the query or its results, so follow-up requests can drop the body.
  • Redirects preserve the method. Unlike POST, a 307 redirect repeats the QUERY. Only 303 switches to GET, and only when the server wants you to fetch results from a different URI.

The canonical example from the RFC:

http
QUERY /feed HTTP/1.1Host: example.orgContent-Type: application/x-www-form-urlencoded
q=foo&limit=10&sort=-published

Same payload you might have POSTed. Different semantics entirely.

For GraphQL, structured JSON filters, SQL, or anything that does not belong in a query string, this is the method the HTTP layer should have had years ago.

When can you actually use it?

The spec is published. Support across the stack is not.

Today, mostly server-side. If you control the HTTP library, the framework router, and the clients calling your API, you can implement QUERY now. Some server environments are already adding support as the RFC settles in.

Browsers are behind. There is no native fetch with method: 'QUERY' in mainstream browsers yet. A WHATWG proposal exists for HTML form method="query" support, but that is still early.

Infrastructure has to catch up. Proxies, CDNs, API gateways, and load balancers need to pass QUERY request bodies through without treating unknown methods as errors. Cache implementations need to build proper cache keys from body content. That takes time.

The adoption pattern will likely look familiar: backend frameworks and API platforms first, then edge providers (Cloudflare and Akamai were on the author list for a reason), then client libraries, then browsers. Public-facing APIs should probably wait until the major intermediaries you sit behind understand the method, unless your callers are also under your control.

For internal services, B2B APIs, and greenfield backends, QUERY is worth designing for now. For a form on a marketing site that needs to work in every browser tomorrow, GET and POST are still the pragmatic choice.

Why this is a bigger deal than it sounds

HTTP methods are infrastructure. They outlive frameworks. GET and POST have been with us for over thirty years. Adding a standard read method with a body is a rare event.

It does not replace GET for simple lookups. It does not replace POST for mutations. It gives complex, read-only operations a first-class home in the protocol, with caching and retry semantics that match what the operation actually does.

If you have been POSTing to /search and telling your CDN "no really, it is read-only," RFC 10008 is the spec that finally agrees with you. The tooling just needs a few years to catch up.