HTTP QUERY Method Explained: RFC 10008, QUERY vs GET vs POST

RFC 10008 defines QUERY, a safe and idempotent HTTP method that carries the query in the request body. What the spec says about Content-Type, caching, Location and Accept-Query, how QUERY compares to GET and POST, and what supports it today.

Ashley Innocent

Ashley Innocent

28 October 2026

HTTP QUERY Method Explained: RFC 10008, QUERY vs GET vs POST

Apidog for Enterprise

On-Premises Deploy

SSO & RBAC

SOC 2 Compliant

Explore Apidog Enterprise

The HTTP QUERY method is a new request method, defined in RFC 10008 (June 2026), that sends a query in the request body and is both safe and idempotent. Think of it as GET with a body: you get POST’s room for complex filters and GET’s guarantees for caching and automatic retries.

If you’ve stuffed a 3 KB filter into a URL, or sent a read-only search as POST and watched your cache and retry logic ignore it, QUERY is the fix. This guide covers what the spec says, how QUERY compares to GET and POST, what supports it today, and how to test a QUERY endpoint with your coding agent.

What is the HTTP QUERY method?

QUERY is an HTTP method that asks the target resource to run the query described in the request content and return the result. The request body and its Content-Type define the query. The method is safe (the client expects no state change) and idempotent (repeating it has the same effect), so clients, proxies and caches can retry and cache it like GET.

The spec is RFC 10008, “The HTTP QUERY Method”, a Proposed Standard published in June 2026 by Julian Reschke (greenbytes), James M. Snell (Cloudflare) and Mike Bishop (Akamai). IANA has added it to the HTTP Method Registry with “safe: yes, idempotent: yes”, right next to the WebDAV-era SEARCH method it almost became.

A QUERY request looks like this:

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

select=surname,givenname,email&limit=10&match=%22email=*@example.*%22

The server answers with 200 OK and the result in the body.

Why GET and POST weren’t enough

You had two options for a complex read before QUERY, and both leak.

GET puts everything in the URL. RFC 10008 lists four problems with that:

  1. Size limits are unknown ahead of time, because a request crosses many systems. RFC 9110 only recommends that senders and recipients support at least 8,000 octets.
  2. Encoding structured data into a valid URI is wasteful.
  3. URIs get logged and bookmarked far more often than request bodies, which is a privacy problem for sensitive filters.
  4. Every combination of query inputs becomes its own resource.

GET with a body isn’t the answer either. RFC 9110 says content in a GET request has no defined semantics. Some servers read it, some drop it, and some proxies reject the request. You can’t count on it across the path.

POST works, but it lies about intent. A POST search runs fine, yet nothing tells a client, cache, proxy or retry library that the operation is read-only. So caches skip it and clients won’t retry it after a dropped connection. If you’ve had to bolt an idempotency key onto a pure read just to make retries safe, you’ve felt this.

QUERY keeps POST’s body and adds GET’s guarantees.

QUERY vs GET vs POST

Here’s the comparison, based on Table 1 of RFC 10008:

Property GET QUERY POST
Safe Yes Yes Potentially no
Idempotent Yes Yes Potentially no
Request body No defined semantics Expected, defines the query Expected
URI for the query itself Yes, by definition Optional, via Location No
URI for the result Optional, via Content-Location Optional, via Content-Location Optional, via Content-Location
Cacheable Yes Yes, body is part of the cache key Only for later GET or HEAD
CORS preflight from browsers Not for simple requests Always Not for simple requests

The short version: use GET when the query fits comfortably in the URL, QUERY when it doesn’t, and POST only when the request changes state. For a refresher on the classic methods, see our guides to HTTP methods and GET vs POST.

What RFC 10008 defines

Content-Type is mandatory

Servers MUST fail a QUERY whose Content-Type is missing or inconsistent with the body. The RFC recommends these status codes:

Location and Content-Location

A server can return two optional headers that turn a QUERY into something you can GET later:

The RFC suggests clients switch to GET on the Location URI for repeat requests, since GET caching is simpler. If you return either header for a query with sensitive data, the URI SHOULD NOT contain sensitive parts of the original body.

Caching

QUERY responses are cacheable. The cache key MUST include the request content and related metadata such as the media type. Caches MAY normalize the body first, for example by removing content encoding or normalizing JSON for a +json type, to get more hits. The spec warns that bad normalization can return the wrong response, so expect CDNs to be careful here.

Redirects

A 301, 302, 307 or 308 means “send the same QUERY to the new URI”. Unlike POST, a QUERY must not be rewritten to GET on a 301 or 302. A 303 See Other means “fetch the result with a GET on this URI”.

The Accept-Query header

Accept-Query is a new response header that advertises QUERY support and the query formats a resource accepts. It’s a Structured Field list, so parse it as one:

Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"

Clients can also discover support with OPTIONS and read the Allow header, or just send the QUERY and handle a 405 Method Not Allowed.

Which tools support QUERY today?

Support is uneven, so test your own stack. Here’s what we confirmed on October 28, 2026:

Tool Result
Node.js 24 http server http.METHODS includes QUERY; a plain server received the method and body
Node.js 24 fetch Sent a QUERY with a JSON body
curl 8.7 curl -X QUERY with -d sent the method and body
Python 3.14 http.client Sent a QUERY with a body
OpenAPI 3.2 The Path Item Object has a query field for QUERY operations
Apidog CLI 2.2.12 The endpoint-create schema accepts "method": "query"

Here’s the curl call we used against a local Node server:

curl -i -X QUERY http://localhost:3000/products \
  -H "Content-Type: application/json" \
  -d '{"q":"running shoe","limit":2}'

The Fetch Standard only forbids a body on GET and HEAD, so browsers can send QUERY with a body. QUERY is not a CORS-safelisted method, though, so every cross-origin QUERY triggers a preflight. Your server must list QUERY in Access-Control-Allow-Methods.

The gaps are in the middle of the network: reverse proxies, API gateways, WAFs and CDNs that allowlist methods or don’t key their cache on the body. Check each hop before you ship. The APIs You Won’t Hate newsletter notes that many web frameworks already handle QUERY directly or through custom-method routing.

How to adopt QUERY without breaking clients

You don’t have to rip out your POST search endpoints.

  1. Add QUERY alongside the POST route. Point both at the same handler. New clients use QUERY; old ones keep working.
  2. Advertise it. Return Accept-Query on the resource and include QUERY in Allow on OPTIONS and 405 responses.
  3. Enforce Content-Type. Return 400 or 415 as the RFC recommends, and 422 for queries that parse but can’t run.
  4. Fall back on 405 or 501. Clients should retry the same body as POST when a hop rejects QUERY.
  5. Fix CORS. Add QUERY to Access-Control-Allow-Methods for browser clients.
  6. Decide on caching. Only enable shared caching where your cache keys on the body. Otherwise return a Location URI and let clients GET it.
  7. Document it. In OpenAPI 3.2, define the operation under query: on the path item:
openapi: 3.2.0
paths:
  /products:
    query:
      summary: Search products
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductQuery'
      responses:
        '200':
          description: Matching products

Short, simple filters can stay as query strings on GET. RFC 10008 itself says that if your query is that short, GET is probably the better choice.

Let your coding agent test a QUERY endpoint with Apidog CLI

A new method means checking the happy path, every error code and the fallback route. Hand that to Claude Code, Codex or Cursor and let it drive the Apidog CLI.

Install the CLI, log in, and add the Apidog skill to your agent:

npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com   # pick your agent when prompted

Then give your agent one prompt:

In Apidog project <projectId>, add a QUERY /products endpoint that takes a
JSON body {q, limit}. Create test cases that assert 200 with an array for a
valid body, 415 for Content-Type text/plain, and 400 with no Content-Type.
Run them against the staging environment and summarize any failures.

The agent reads each schema, validates its payload and only then writes:

apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create --file endpoint.json
apidog endpoint create --project <projectId> --file endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json

The endpoint.json it writes sets "method": "query", which the CLI’s endpoint-create schema lists alongside get, post and the WebDAV methods. Add --upload-report to see the run in the Apidog app. The same apidog run command with -r junit drops into CI; see how to run API tests in CI with apidog run and how to use the Apidog CLI in Claude Code. Apidog’s Free plan covers up to 4 users.

FAQ

Is the HTTP QUERY method an official standard? Yes. RFC 10008 is a Standards Track, Proposed Standard RFC published in June 2026, and IANA lists QUERY in the HTTP Method Registry as safe and idempotent.

Is QUERY just GET with a body? Close, but it’s better defined. RFC 9110 gives a GET body no semantics, so intermediaries can ignore or reject it. QUERY makes the body the query, requires a Content-Type, and folds the body into the cache key.

When should I use QUERY instead of POST? Use QUERY for any read-only search or filter that’s too large or too sensitive for a URL. Keep POST for requests that create or change something.

Can browsers send QUERY requests? Yes, through fetch with a custom method. Cross-origin QUERY requests always need a CORS preflight, so your server must allow the method.

Are QUERY responses cached? They can be. Caches must include the request body and its metadata in the cache key. Many CDNs and proxies don’t do that yet, so check yours or return a Location URI that clients can GET.

Does OpenAPI support QUERY? OpenAPI 3.2 adds a query field to the Path Item Object for QUERY operations, so you can document them without extensions.

Explore more

OpenAI CLI: Install It and Call the OpenAI API From Your Terminal

OpenAI CLI: Install It and Call the OpenAI API From Your Terminal

The OpenAI CLI is OpenAI's official openai command for calling the REST API from your terminal. Install, auth, Responses, files, batches and local token counts, plus how it compares with Codex CLI and the legacy Python openai command.

28 October 2026

Anthropic S-1: What the IPO Filing Means for Claude API Developers

Anthropic S-1: What the IPO Filing Means for Claude API Developers

Anthropic filed its S-1 on October 26, 2026. What the filing says about consumption revenue, compute capacity, rate limits, model deprecation and pricing, what changes for Claude API developers, and a resilience checklist you can test with an agent.

28 October 2026

Best LLM for Browser Agents in 2026: Models Ranked on Score and Cost

Best LLM for Browser Agents in 2026: Models Ranked on Score and Cost

Which model should drive your browser agent? Vendor-reported OSWorld scores, prices read today, screenshot vs DOM mode, a 30-step cost-per-task example, and when to skip the browser and test the API with Apidog CLI.

27 October 2026

Practice API Design-first in Apidog

Discover an easier way to build and use APIs