Basics
curl URL
GET request, body printed to stdout
curl -i URL
Include response headers in output
curl -I URL
HEAD request, only show response headers
curl -v URL
Verbose, show request and response headers
curl -s URL
Silent mode, no progress meter or errors
curl -sS URL
Silent but still show errors (most common combo)
curl --version
Show curl version and supported features
curl --help all
Print every option (the kitchen sink)
HTTP Methods
curl -X POST URL
POST request (with no body)
curl -X PUT URL
PUT request
curl -X PATCH URL
PATCH request
curl -X DELETE URL
DELETE request
curl -X OPTIONS URL
OPTIONS request (CORS preflight)
curl --get -d "q=foo" URL
GET with query string from -d data
curl -d "x=1&y=2" URL
POST form-encoded (-d implies -X POST)
Headers
curl -H "Accept: application/json" URL
Set request header
curl -H "X-Custom: value" -H "X-Other: 2" URL
Multiple headers, repeat -H
curl -H "User-Agent: my-bot/1.0" URL
Override User-Agent header
curl -A "my-bot/1.0" URL
Shortcut for User-Agent
curl -e "https://referer.example" URL
Set Referer header
curl -H "Host: example.com" IP_URL
Override Host header (test SNI / virtual hosts)
curl -H "X-Foo;" URL
Send empty header (semicolon at end)
curl -H "Accept-Encoding: gzip" --compressed URL
Auto-decompress gzip / br response
Authentication
curl -u user:pass URL
HTTP Basic auth
curl -u user URL
Basic auth, prompt for password (more secure than inline)
curl -H "Authorization: Bearer TOKEN" URL
Bearer token (OAuth2, JWT, API tokens)
curl -H "Authorization: Token $(cat ~/.token)" URL
Read token from a file (do not paste secrets)
curl --digest -u user:pass URL
HTTP Digest auth
curl --ntlm -u user:pass URL
NTLM auth (Windows / Active Directory)
curl --aws-sigv4 "aws:amz:us-east-1:s3" -u KEY:SECRET URL
AWS SigV4 signing (S3, etc.)
curl --netrc-file ~/.netrc URL
Read credentials from .netrc
Request Body: JSON
curl -H "Content-Type: application/json" -d '{"a":1}' URL
POST JSON body
curl --json '{"a":1}' URL
Shortcut, sets Content-Type and Accept to JSON (curl 7.82+)
curl --json @body.json URL
JSON body from a file
curl -d @body.json -H "Content-Type: application/json" URL
Same, classic syntax
cat body.json | curl --json @- URL
JSON body from stdin (--json @- means read stdin)
curl -d '{"id":"'"$ID"'"}' URL
Inject shell variable into JSON (mind the quoting)
Request Body: Forms & Files
curl -d "name=Ada&role=admin" URL
URL-encoded form (application/x-www-form-urlencoded)
curl --data-urlencode "q=hello world" URL
URL-encode a single field automatically
curl -F "field=value" URL
Multipart form (-F implies POST and multipart/form-data)
Multipart file upload (the @ reads from disk)
Multipart file with explicit MIME type
curl -F "file=@-;filename=stdin.txt" URL
Multipart upload from stdin
curl --data-binary @file.bin URL
Raw body, no encoding (use for binary uploads)
curl -T file.txt URL
PUT upload of a single file (--upload-file)
Cookies & Sessions
curl -b "session=abc123" URL
Send cookie with request
curl -b cookies.txt URL
Read cookies from a Netscape-format file
curl -c cookies.txt URL
Save cookies received from server
curl -b cookies.txt -c cookies.txt URL
Read AND save (persistent session jar)
curl --cookie-jar /tmp/cj URL
Long form of -c
Output: Saving & Piping
curl -o file.html URL
Save body to specific filename
curl -O URL
Save with the URL's basename (e.g. index.html)
curl -OJ URL
Use Content-Disposition filename if given
curl -D headers.txt URL
Save response headers to a file
curl -w "%{http_code}\n" -o /dev/null -s URL
Print only the status code (great for scripts)
curl -s URL | jq .
Pretty-print JSON response with jq
curl URL > file.bin
Redirect via shell (same as -o)
Redirects, Retries & Timeouts
curl -L URL
Follow 3xx redirects
curl -L --max-redirs 5 URL
Follow up to 5 redirects (default: 50)
curl --retry 3 URL
Retry up to 3 times on transient errors
curl --retry 3 --retry-delay 2 URL
Retry with 2s delay between attempts
curl --retry 5 --retry-all-errors URL
Retry on any error (incl. non-transient)
curl --connect-timeout 5 URL
Time limit for the TCP connect phase
curl --max-time 30 URL
Total time limit for the whole request
curl --fail URL
Exit non-zero on HTTP error (4xx/5xx)
curl -fsSL URL | sh
Common installer pattern: fail-loud, silent, follow redirects
SSL / TLS
curl -k URL
Insecure, skip cert verification (DEBUG ONLY)
curl --cacert ca.pem URL
Use a specific CA bundle for verification
curl --cert client.pem --key client.key URL
Mutual TLS with client cert + key
curl --tlsv1.3 URL
Force TLS 1.3 minimum
curl --tls-max 1.2 URL
Limit to TLS 1.2 max (legacy testing)
curl --resolve example.com:443:1.2.3.4 URL
Pin DNS to a specific IP (test before flipping records)
Proxy
curl -x http://proxy:8080 URL
Use HTTP proxy
curl --socks5 host:1080 URL
Use SOCKS5 proxy
curl -x http://user:pass@proxy:8080 URL
Authenticated proxy
HTTPS_PROXY=http://proxy:8080 curl URL
Use the standard env var
curl --noproxy "*" URL
Force direct, ignore env proxy settings
HTTP/2 & HTTP/3
curl --http2 URL
Force HTTP/2
curl --http2-prior-knowledge URL
HTTP/2 cleartext, skip upgrade dance
curl --http3 URL
Force HTTP/3 / QUIC (build dependent)
curl --http1.1 URL
Force HTTP/1.1 (debug fallback path)
Performance & Timing
curl -w "@curl-format.txt" -o /dev/null -s URL
Per-stage timing breakdown using a format file
curl -w "%{time_total}\n" -o /dev/null -s URL
Total request time only
curl -w "%{time_namelookup} %{time_connect} %{time_starttransfer}\n" URL
DNS / connect / TTFB triad
curl --limit-rate 200K URL
Throttle bandwidth to 200 KB/s (testing slow clients)
curl --range 0-1023 URL
Range request, first 1024 bytes
curl -C - -O URL
Resume an interrupted download
Debug & Inspect
curl -v URL 2>&1 | grep '^>'
Show only the request lines
curl --trace-ascii trace.log URL
Full ASCII trace of bytes sent and received
curl --trace - URL
Full hex+ASCII trace to stdout
curl -v --trace-time URL
Verbose with timestamps on every line
curl --resolve api.example:443:127.0.0.1 -v URL
Pin DNS to localhost (test against a local mock)
Useful Recipes
JSON POST with bearer token
curl -sS -X POST https://api.example.com/v1/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"
[email protected]","name":"Ada"}'
Per-stage timing breakdown
cat > curl-format.txt <<'EOF'
DNS: %{time_namelookup}s
Connect: %{time_connect}s
TLS: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
EOF
curl -w "@curl-format.txt" -o /dev/null -s https://example.com
Drop this curl-format.txt into your home dir. The single most useful debugging tool for slow APIs.
Test an API only by status code (CI-friendly)
code=$(curl -o /dev/null -s -w "%{http_code}" https://api.example.com/health)
[ "$code" = "200" ] || { echo "FAIL: $code"; exit 1; }
Stream Server-Sent Events
curl -N -H "Accept: text/event-stream" https://stream.example.com/events
-N disables output buffering so events appear in real time.
Multipart upload with extra fields
curl -F "title=My Photo" \
-F "tags=cat,sunset" \
-F "
[email protected];type=image/jpeg" \
https://api.example.com/photos
Resilient downloader (retries + resume)
curl -fL --retry 5 --retry-delay 2 --retry-all-errors \
-C - -O https://files.example.com/big.iso
Pretty-print and filter JSON with jq
curl -sS https://terminalfeed.io/api/briefing | jq '.btc.price'
Convert curl to fetch / Python / axios
Useful when porting an API call from a working curl into your codebase.
Config: .curlrc
~/.curlrc
Per-user defaults file (one option per line, no leading dashes)
--silent --show-error
Common .curlrc default: -sS for every invocation
--location
.curlrc default: follow redirects unless overridden
curl -q URL
Disable .curlrc for this invocation (clean slate)
curl -K config.txt URL
Load a specific config file
Common Exit Codes
6
Could not resolve host (DNS)
7
Failed to connect (host up but port closed / refused)
22
HTTP error and --fail was used (4xx/5xx)
28
Operation timeout (--max-time / --connect-timeout)
35
SSL connect error (handshake failed)
52
Empty reply from server
60
Peer cert cannot be verified (CA mismatch)