Skip to content
ADP
API Design PrincipleBETA

[ADP-116] QUERY

Overview

The HTTP QUERY method, defined in RFC 10008, is a safe and idempotent request method that carries a request body describing how the request is to be processed by the target resource. It fills the gap between GET, which cannot carry a request body, and POST, which is neither safe nor guaranteed idempotent — allowing complex queries to be expressed in the request body while retaining GET's safety and cacheability guarantees.

Guidance

  • QUERY requests MUST be treated as safe: the client does not request or expect any change to the state of the target resource.
  • QUERY requests MUST be treated as idempotent and MAY be retried or repeated automatically, for instance after a connection failure.
  • QUERY being safe and idempotent says nothing about access control; endpoints MUST still enforce authentication and authorization independently. See ADP-123: Authorization.
  • The request body MUST contain a representation describing the query to be performed; the Content-Type header MUST identify the media type of that representation.
  • If the request lacks media type information, the server MUST fail the request with a 4xx status code, typically 400 Bad Request.
  • If the request specifies a media type the resource does not support, the server SHOULD respond with 415 Unsupported Media Type.
  • If the media type is supported and the content is well-formed, but the query cannot be processed due to its actual contents (for example, a syntactically valid query that references a non-existent field), the server SHOULD respond with 422 Unprocessable Content.
  • If the client requests a response media type via Accept that the resource does not support, the server SHOULD respond with 406 Not Acceptable.
  • Error responses for QUERY (400/415/422/406) MUST follow the HTTP Problem Details format. See ADP-401: HTTP Problem Basics.
  • A successful response (2xx) MAY include a Content-Location header identifying a resource corresponding to the query results, allowing the client to retrieve the same results later with a plain GET. When the query contains sensitive information, the server MUST NOT embed any sensitive portion of the request content in that Content-Location URI (RFC 10008 §4), since URIs are logged far more widely than request bodies.
  • Responses to QUERY requests SHOULD be cacheable. Any cache key MUST incorporate the request content and related metadata, since the query is expressed in the body rather than the URI. See ADP-361: HTTP Caching.
  • Resources SHOULD advertise QUERY support and the accepted query media types using the Accept-Query response header. See below.
  • SHOULD prefer QUERY over a POST /resources/search-style endpoint only when the query complexity exceeds what a query string can reasonably carry. For the default query-string-based approach, see ADP-311: Filtering and ADP-318: Query Parameter Convention.

Accept-Query header

A resource MAY use the Accept-Query response header to signal support for the QUERY method and identify the query media types it accepts:

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

Example

Request:

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

select=surname,givenname,email&limit=10

Response:

http
HTTP/1.1 200 OK
Content-Type: application/json

[
  { "surname": "Smith", "givenname": "John", "email": "smith@example.org" },
  { "surname": "Jones", "givenname": "Sally", "email": "sally.jones@example.com" }
]

Adoption Checklist

Before adopting QUERY in production, verify each of the following — as of 2026-07, support is uneven across the ecosystem:

  • Client: modern fetch/XMLHttpRequest support arbitrary method strings, but QUERY is not in the CORS-safelisted method set, so cross-origin calls MUST correctly handle the standard OPTIONS preflight request.
  • Server runtime: confirm your HTTP server/parser recognizes QUERY as a valid method string rather than rejecting the connection outright.
  • Intermediaries / body integrity: proxies, load balancers, and WAFs that assume safe methods carry no body MAY strip, buffer, or desync the QUERY request body — producing silent wrong results or a request-smuggling surface. Verify every hop on the request path forwards the body intact for QUERY.
  • Edge/CDN: some CDNs enforce a fixed allow-list of HTTP methods and reject anything outside it; verify your edge layer's documented allowed-methods configuration before relying on QUERY reaching your origin.
  • API gateway: some managed API gateways require every supported method to be explicitly declared per route, and their declaration syntax may not yet recognize QUERY; verify whether your gateway supports it directly or requires a wildcard/proxy route.
  • Shared cache: confirm any shared/reverse cache in front of your API can incorporate request body content into its cache key — otherwise the cacheability benefit of QUERY does not apply.
  • OpenAPI tooling: query as a first-class operation was only added in OpenAPI Specification 3.2; confirm your spec version and tooling (validators, codegen, documentation renderers) support it before documenting QUERY endpoints in OpenAPI.

References

Changelog

  • 2026.07.08 Initial version.