Example: POST with Query Params and a JSON Body
curl -X POST 'https://api.example.com/search?mode=advanced&debug=false' \
-H 'Content-Type: application/json' \
-d '{"query":"bear","from":0}'
This shape is everywhere (Stripe webhooks, search APIs) and breaks converters that assume data flags imply the query string. Rules we follow: **URL is authority for params, body is authority for payload, -G is what turns data into the URL instead.**
Why it trips people up:
- The query params are routing/behavior switches (
mode,version,dryRun), not the payload. Copying-dcontent into the query string, or vice versa, changes which layer of the server sees your data. -X POSThere is load-bearing, unlike the no-op-X GET: remove it and curl still POSTs because-dimplies the method — but readers of the command can't see that.- Quoting matters twice over: the URL contains
&, which backgrounds commands in unquoted bash, and the JSON needs single quotes to stay literal. This is quoting hell in a single line.
FAQ
Is ?mode=advanced in the URL less secure than in the body? It's more exposed: query strings appear in access logs at every hop, while POST bodies usually don't. Put switches there, secrets never.
Why do webhooks use this shape? Query params survive on the URL even when middleboxes or queues round-trip the body — and signature verification reads the body verbatim, so you don't want structural switches mixed into it.