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.
| Flag | What it does |
|---|---|
-X POST | Set 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. |
-I | Fetch headers only (HEAD request). |
-i | Include response headers in output. |
-v | Verbose: 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 -20Request body
| Flag | What it does |
|---|---|
-d '{"key":"value"}' | Send a request body (implies POST if -X not set). |
-d @payload.json | Read 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
| Flag | What it does |
|---|---|
-o file.json | Write response body to a file. |
-O | Write response to a file named by the URL. |
-s | Silent; suppress progress meter. |
-S | Show errors even with -s. |
--fail | Exit with status 22 on HTTP error responses (4xx, 5xx). |
-w "%{http_code}" | Print a custom write-out variable after the response. |
--limit-rate 1M | Throttle download speed. |
-C - | Resume an interrupted download. |
--compressed | Request 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
| Flag | What it does |
|---|---|
-L | Follow redirects. |
--max-redirs 5 | Limit redirect chain length. |
-k | Skip TLS certificate verification. Development only. |
--cacert ca.pem | Use a custom CA bundle. |
--cert client.pem --key client.key | Mutual TLS: send a client certificate. |
--resolve example.com:443:127.0.0.1 | Override DNS for one host; useful for local HTTPS testing. |
-x http://proxy:8080 | Route through an HTTP proxy. |
--noproxy localhost,127.0.0.1 | Bypass proxy for listed hosts. |
Use --resolve instead of editing /etc/hosts when testing a new server before DNS propagates.
Auth flags
| Flag | What it does |
|---|---|
-u user:pass | HTTP Basic auth. |
-u user | Prompt for password interactively. |
--oauth2-bearer $TOKEN | OAuth 2.0 Bearer token in header. |
--negotiate -u : | Kerberos/NTLM negotiation. |
-b "session=abc123" | Send a cookie string. |
-b cookies.txt | Send cookies from a file (Netscape format). |
-c cookies.txt | Save 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/statusCommon gotchas
-dwithout-Xdefaults to POST but does not setContent-Type. Always set the header explicitly.-kdisables certificate verification completely, not just hostname checking. Never use in production scripts; use--cacertfor self-signed CAs.-Lfollows redirects but drops headers likeAuthorizationby default on cross-origin redirects. Use--location-trustedto 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/nullfor clean output.-d '@file'reads fromfile;-d @file(no quotes) works the same way in bash but looks like a bare@in some shells. Quote consistently.--failexits non-zero on 4xx/5xx but still writes the response body to stdout. Redirect to-o /dev/nullif you only want the exit code.