Overview

curl is the universal HTTP client for testing, scripting, and debugging. This card covers the flags and patterns you reach for when building or debugging APIs. For parsing JSON responses, pipe to jq-syntax.

Method and headers

Set the method and headers explicitly; do not rely on curl’s defaults when the method matters.

FlagWhat it does
-X POSTSet the HTTP method.
-H "Content-Type: application/json"Add a request header.
-H "Authorization: Bearer $TOKEN"Auth header from a shell variable.
-H "Accept: application/json"Request JSON response.
-IFetch headers only (HEAD request).
-iInclude response headers in output.
-vVerbose: show request and response headers, TLS handshake.
--trace-ascii -Full wire trace to stdout.

Combine -i with jq to see both headers and a pretty-printed body in one pass:

curl -i https://api.example.com/users | head -20

Request body

FlagWhat it does
-d '{"key":"value"}'Send a request body (implies POST if -X not set).
-d @payload.jsonRead body from a file.
--data-raw '{"key":"value"}'Send body literally; @ is not treated as a file reference.
-F "file=@photo.jpg"Multipart form upload.
-F "file=@photo.jpg;type=image/jpeg"Multipart with explicit MIME type.
--data-urlencode "name=hello world"URL-encode a form field.
-G -d "q=test"Convert -d data to a query string (GET request).

Always pair -d '{"...}' with -H "Content-Type: application/json". Without it, curl sends application/x-www-form-urlencoded.

Output and download

FlagWhat it does
-o file.jsonWrite response body to a file.
-OWrite response to a file named by the URL.
-sSilent; suppress progress meter.
-SShow errors even with -s.
--failExit with status 22 on HTTP error responses (4xx, 5xx).
-w "%{http_code}"Print a custom write-out variable after the response.
--limit-rate 1MThrottle download speed.
-C -Resume an interrupted download.
--compressedRequest gzip/deflate compression; decompress automatically.

Combine --fail --silent --show-error (or --fail -sS) for scripts where you want to abort on error without progress noise.

Redirects, TLS, and proxies

FlagWhat it does
-LFollow redirects.
--max-redirs 5Limit redirect chain length.
-kSkip TLS certificate verification. Development only.
--cacert ca.pemUse a custom CA bundle.
--cert client.pem --key client.keyMutual TLS: send a client certificate.
--resolve example.com:443:127.0.0.1Override DNS for one host; useful for local HTTPS testing.
-x http://proxy:8080Route through an HTTP proxy.
--noproxy localhost,127.0.0.1Bypass proxy for listed hosts.

Use --resolve instead of editing /etc/hosts when testing a new server before DNS propagates.

Auth flags

FlagWhat it does
-u user:passHTTP Basic auth.
-u userPrompt for password interactively.
--oauth2-bearer $TOKENOAuth 2.0 Bearer token in header.
--negotiate -u :Kerberos/NTLM negotiation.
-b "session=abc123"Send a cookie string.
-b cookies.txtSend cookies from a file (Netscape format).
-c cookies.txtSave response cookies to a file.

For Bearer auth, -H "Authorization: Bearer $TOKEN" and --oauth2-bearer $TOKEN are equivalent; the header form works everywhere.

Common HTTP test patterns

Ready-to-paste patterns for API development.

# GET with JSON response, pretty-printed
curl -sS https://api.example.com/users | jq '.'
 
# POST JSON body
curl -sS -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "alice"}' | jq '.'
 
# PUT with auth
curl -sS -X PUT https://api.example.com/users/1 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "alice updated"}' | jq '.'
 
# Check HTTP status code only
curl -o /dev/null -sS -w "%{http_code}\n" https://api.example.com/health
 
# Download a file, resume if interrupted
curl -L -C - -o large-file.zip https://example.com/large-file.zip
 
# Test HTTPS with a local server, bypassing cert check
curl -k https://localhost:8443/api/status

Common gotchas

  • -d without -X defaults to POST but does not set Content-Type. Always set the header explicitly.
  • -k disables certificate verification completely, not just hostname checking. Never use in production scripts; use --cacert for self-signed CAs.
  • -L follows redirects but drops headers like Authorization by default on cross-origin redirects. Use --location-trusted to keep headers, but only when the redirect destination is trusted.
  • -w "%{http_code}" prints after the body on the same line without a newline. Use -w "\n%{http_code}\n" or redirect body to -o /dev/null for clean output.
  • -d '@file' reads from file; -d @file (no quotes) works the same way in bash but looks like a bare @ in some shells. Quote consistently.
  • --fail exits non-zero on 4xx/5xx but still writes the response body to stdout. Redirect to -o /dev/null if you only want the exit code.