Quick reference tables
Basic requests
| Command | What it does |
|---|---|
curl https://example.com | GET request, print body |
curl -o file.html https://example.com | Save response to file |
curl -O https://example.com/file.zip | Save with original filename |
curl -L https://example.com | Follow redirects |
curl -s https://example.com | Silent (no progress bar) |
curl -S https://example.com | Show errors even when silent |
curl -v https://example.com | Verbose — show all headers |
curl --trace - https://example.com | Full hex dump of all traffic |
Headers
| Command | What it does |
|---|---|
curl -I https://example.com | HEAD request — headers only |
curl -i https://example.com | Include response headers in output |
curl -H "Authorization: Bearer TOKEN" | Add a header |
curl -H "Content-Type: application/json" | Set content type |
curl -H "Accept: application/json" | Set accept header |
curl -H "X-Custom: value" -H "X-Other: val" | Multiple headers |
curl -A "MyBot/1.0" | Set User-Agent |
curl -e "https://referrer.com" | Set Referer |
POST requests
| Command | What it does |
|---|---|
curl -X POST https://api.example.com | POST with no body |
curl -d "key=value" https://api.example.com | POST form data |
curl -d '{"name":"Alice"}' -H "Content-Type: application/json" url | POST JSON |
curl --data-urlencode "name=Alice Smith" url | URL-encode data |
curl -d @data.json -H "Content-Type: application/json" url | POST from file |
curl -X PUT -d '{}' url | PUT request |
curl -X PATCH -d '{}' url | PATCH request |
curl -X DELETE url | DELETE request |
Authentication
| Command | What it does |
|---|---|
curl -u user:password url | Basic auth |
curl -H "Authorization: Bearer TOKEN" url | Bearer token |
curl -H "Authorization: Basic BASE64" url | Basic auth manually |
curl --oauth2-bearer TOKEN url | OAuth2 bearer |
curl --cert cert.pem --key key.pem url | Client certificate auth |
curl --cacert ca.pem url | Custom CA certificate |
curl -k url | Skip SSL verification (dev only) |
File upload
| Command | What it does |
|---|---|
curl -F "[email protected]" url | Upload file (multipart) |
curl -F "[email protected];type=image/jpeg" url | Upload with MIME type |
curl -F "[email protected]" -F "name=Alice" url | Upload file + form field |
curl -T file.txt url | PUT upload (FTP-style) |
curl --data-binary @file.bin url | Binary POST |
Response control
| Command | What it does |
|---|---|
curl -w "%{http_code}" url | Print only status code |
curl -w "%{time_total}" url | Print total request time |
curl -D headers.txt url | Save headers to file |
curl -D - url | Print headers to stdout |
curl --max-time 10 url | Timeout after 10 seconds |
curl --connect-timeout 5 url | Connection timeout |
curl --retry 3 url | Retry on failure |
curl --retry-delay 2 url | Delay between retries |
curl -r 0-1023 url | Download only first 1024 bytes |
Cookies
| Command | What it does |
|---|---|
curl -c cookies.txt url | Save cookies to file |
curl -b cookies.txt url | Send cookies from file |
curl -b "session=abc123" url | Send cookie string |
curl -c cookies.txt -b cookies.txt url | Save and send cookies |
Proxy
| Command | What it does |
|---|---|
curl -x http://proxy:8080 url | Use HTTP proxy |
curl -x socks5://localhost:1080 url | Use SOCKS5 proxy |
curl --noproxy "localhost,127.0.0.1" url | Bypass proxy |
Detailed sections
Inspecting APIs — the daily workflow
# Check if an API is up and what it returns
curl -s https://api.example.com/health | jq
# GET with auth, pretty-print JSON response
curl -s \
-H "Authorization: Bearer $TOKEN" \
https://api.example.com/users \
| jq '.data[] | {id, name, email}'
# POST JSON and pretty-print response
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "Alice", "role": "admin"}' \
https://api.example.com/users \
| jq
# See only the status code (useful in scripts)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health)
echo "Status: $STATUS"
[ "$STATUS" = "200" ] && echo "OK" || echo "FAIL"
Timing breakdown — debug slow APIs
curl -w "
time_namelookup: %{time_namelookup}s
time_connect: %{time_connect}s
time_appconnect: %{time_appconnect}s
time_pretransfer: %{time_pretransfer}s
time_redirect: %{time_redirect}s
time_starttransfer: %{time_starttransfer}s
----------
time_total: %{time_total}s
" -s -o /dev/null https://api.example.com
# What each means:
# time_namelookup → DNS resolution
# time_connect → TCP connection
# time_appconnect → TLS handshake
# time_pretransfer → headers sent
# time_starttransfer → first byte received (TTFB)
# time_total → everything done
Downloading files reliably
# Download with progress bar + resume support
curl -L -C - -o large_file.zip https://example.com/large_file.zip
# Download multiple files
curl -O https://example.com/file1.zip \
-O https://example.com/file2.zip
# Download only if file has changed (conditional GET)
curl -z existing_file.zip -O https://example.com/file.zip
# Parallel downloads (with GNU parallel)
cat urls.txt | parallel curl -O {}
# Download and extract immediately (no temp file)
curl -s https://example.com/archive.tar.gz | tar xzf -
Testing webhooks locally
# Simulate a webhook POST to your local server
curl -X POST http://localhost:3000/webhook \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: mysecret" \
-d '{"event": "user.created", "data": {"id": 42, "name": "Alice"}}'
# Simulate GitHub webhook
curl -X POST http://localhost:3000/github-webhook \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: push" \
-H "X-Hub-Signature-256: sha256=..." \
-d @github_push_payload.json
Useful one-liners
# Get your public IP
curl -s ifconfig.me
# Check HTTP headers of any site
curl -sI https://example.com
# Follow all redirects, show final URL
curl -sIL https://t.co/shortlink | grep -i "location" | tail -1
# Download and run an install script (inspect first!)
curl -sL https://get.example.com/install.sh | bash
# Test CORS headers
curl -sI -X OPTIONS \
-H "Origin: https://myapp.com" \
-H "Access-Control-Request-Method: POST" \
https://api.example.com/users
# Check SSL certificate expiry
curl -sI https://example.com 2>&1 | grep -i "expire"
# Or more directly:
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -dates
# POST to an API and extract a field from the JSON response
TOKEN=$(curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"secret"}' \
https://api.example.com/auth \
| jq -r '.token')
echo "Got token: $TOKEN"
Scripting with curl
#!/bin/bash
set -e
API_BASE="https://api.example.com"
TOKEN="$API_TOKEN" # from environment
# Helper function
api_call() {
local method=$1
local path=$2
local data=${3:-""}
if [ -n "$data" ]; then
curl -sf -X "$method" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$data" \
"$API_BASE$path"
else
curl -sf -X "$method" \
-H "Authorization: Bearer $TOKEN" \
"$API_BASE$path"
fi
}
# Use the helper
USERS=$(api_call GET /users)
echo "$USERS" | jq '.[].email'
api_call POST /users '{"name":"Bob","email":"[email protected]"}'
api_call DELETE /users/42
curl vs wget — when to use which
| Task | curl | wget |
|---|---|---|
| API testing | curl -X POST ... | awkward |
| Download a file | both work | wget url is simpler |
| Resume download | curl -C - | wget -c |
| Mirror a website | not ideal | wget -r |
| Scripting/piping | great | less flexible |
| Send headers | -H | --header |
| Quiet mode | -s | -q |
Related Reading.
Cheatsheet 9 min read
Linux & Bash Cheat Sheet: Commands Every Dev Needs
Complete Linux and Bash reference — file operations, permissions, processes, grep, find, networking, pipes, cron jobs, SSH, and shell scripting.
Vishnu Damwala
Cheatsheet 7 min read
SSH & GPG Cheat Sheet: Keys, Tunnels & Signed Commits
Complete SSH and GPG reference — key generation, ssh-agent, config file aliases, port forwarding, database tunneling, GPG signing, and signed git commits.
Vishnu Damwala
Cheatsheet 8 min read
Vim Cheat Sheet: Modes, Navigation, Editing & Config
Complete Vim reference covering modes, movement, editing commands, search and replace, visual mode, split panes, macros, text objects, and a starter .vimrc.
Vishnu Damwala