cURLParse cURL Converter

GET with a Body: The Request Shape Nobody Tells You About

cURLParse — Convert cURL Commands to Python, Node.js, Go & Rust Guides · Updated 2026-10-01 · All guides

RFC 9110 is blunt: GET payloads have "no defined semantics" and servers may reject them. Yet curl -G --data-urlencode "q=cat" sends query params on a GET, Elasticsearch's _search accepts a real JSON body on GET, and a surprising number of internal APIs ship this way. Knowing why it's contentious tells you when you can safely use it.

Why servers tolerate or reject it

A GET body must survive three proxies, a CDN cache, and two load balancers between client and app. Some of those will strip the body (cache-friendly behavior), and several CDNs hard-400 it as a request-smuggling-defense measure. Your dev server accepting the pattern is not evidence production will.

Query string vs body: the actual tradeoff

Query strings get logged in plain text in every intermediary access log, capped at 8–12KB by common defaults, and double as cache keys. A body for a read avoids both the length limit and the log leak. That's the real argument for POST-as-search, which is why Elasticsearch and GraphQL adopted POST for complex reads — and why curl's -G flag exists: it puts the data in the URL while keeping the method GET, the honest version of the pattern.

curl -G 'https://api.example.com/search' \
  --data-urlencode 'q={"match":{"title":"hello"}}'

This site's converter emits query-string params for -G and warns on -X GET -d, because those two flags together mean someone wants a body on a GET, which works in Postman and dies behind Cloudflare — a class of bug that costs an afternoon every time. The POST with query params example shows the inverse shape, which is unambiguous and always safe.

FAQ

Can I send a JSON body with GET in production? Not over the public internet. Behind your own load balancer with a server that documents support (Elasticsearch does), it works; on the open web, pick POST or use query params via -G.

Why does -d turn my GET into a POST? Bare -d implies POST by design. Add -G and curl moves the data into the query string instead, keeping the method GET.

Why is my search endpoint logged with my query in plaintext? Because query strings land in access logs at every hop. Anything sensitive in a search belongs in a POST body — that's the same reason passwords go in POST bodies.

Developer Sponsor / Partner
Copied to clipboard!