Skip to content

cURL

Test the QUERY method straight from your terminal. curl accepts -X QUERY natively — no patches, no custom builds.


Terminal window
curl -X QUERY https://api.example.com/users \
-d '{"city": "New York", "active": true}'

Terminal window
curl -X QUERY https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"city": "New York", "active": true, "limit": 25}'

Terminal window
curl -v -X QUERY https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"city": "New York"}'

Expected output:

> QUERY /users HTTP/2
> Host: api.example.com
> Content-Type: application/json
> Content-Length: 22
>
< HTTP/2 200
< Content-Type: application/json
< Cache-Control: max-age=60

QUERY is cacheable — the second identical request may be served from cache.

Terminal window
curl -s -o /dev/null -w "HTTP %{http_code} | Time: %{time_total}s\n" \
-X QUERY https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"city": "New York"}'
curl -s -o /dev/null -w "HTTP %{http_code} | Time: %{time_total}s\n" \
-X QUERY https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"city": "New York"}'

With Content-Location in the response, intermediaries can serve the cached version.


Terminal window
# Server running on localhost:3000
curl -X QUERY http://localhost:3000/api/products \
-H "Content-Type: application/json" \
-d '{
"category": "electronics",
"max_price": 500,
"sort": "price_asc"
}'

With formatted output:

Terminal window
curl -s -X QUERY http://localhost:3000/api/products \
-H "Content-Type: application/json" \
-d '{"category": "electronics"}' | jq .

HTTPie also accepts custom methods:

Terminal window
# Basic
http QUERY https://api.example.com/users \
city="New York" active:=true
http QUERY http://localhost:3000/api/products \
Content-Type:application/json \
category="electronics" max_price:=500
http --verbose QUERY https://api.example.com/users \
city="New York"

For complex queries, use a file:

Terminal window
# query.json
cat > query.json << 'EOF'
{
"filters": {
"city": "New York",
"active": true,
"tags": ["premium", "verified"]
},
"pagination": { "limit": 50, "offset": 0 },
"fields": ["id", "name", "email"]
}
EOF
curl -X QUERY https://api.example.com/users \
-H "Content-Type: application/json" \
-d @query.json

Flag Description Example
-X QUERY Set the HTTP method curl -X QUERY url
-d '...' Send body (string) -d '{"key":"val"}'
-d @file Send body from file -d @query.json
-H Add header -H "Content-Type: application/json"
-v Verbose mode Shows full request/response
-s Silent mode Suppresses progress bar
-o /dev/null Discard body Useful with -w for metrics
-w Output format -w "%{http_code} %{time_total}"
--follow Follow redirects (new) Preserves QUERY method on redirect
-i Show response headers Useful to check Cache-Control
--json JSON Content-Type shortcut curl --json '{}' -X QUERY url

Terminal window
# Combine --json with -X QUERY (curl 7.82+)
curl --json '{"active": true}' -X QUERY https://api.example.com/users
curl -s -o /dev/null -w "%{time_total}\n" \
-X QUERY https://api.example.com/users \
-d '{"city": "New York"}'
curl -X OPTIONS https://api.example.com/users -i

Modern curl offers --follow which respects HTTP semantics — if the server responds with 303, the redirect uses GET. With -L, the original method is blindly repeated on all hops.

Terminal window
# Correct
curl --follow -X QUERY https://api.example.com/search \
-H "Content-Type: application/json" \
-d '{"q": "test"}'
curl -L -X QUERY https://api.example.com/search # ⚠️ may repeat QUERY incorrectly