Quick Answer:
curl https://example.comfetches a page.curl -o file.zip URLdownloads a file.curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' URLsends JSON.curl -I URLshows headers only.curl -v URLshows full request/response debug.
Basic Requests
# GET (default)
curl https://example.com
curl https://api.example.com/users
# Follow redirects
curl -L https://example.com
# Silent (no progress bar)
curl -s https://api.example.com/data
# Silent mode (hide progress bar, show errors)
curl -sS https://api.example.com/data
# Save output to file
curl -o output.html https://example.com
curl -O https://example.com/file.zip # Keep original filename
# Show response headers only
curl -I https://example.com
# Show headers + body
curl -i https://example.com
# Verbose (debug mode — see full request/response)
curl -v https://example.com
HTTP Methods
# GET
curl https://api.example.com/users
# POST
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Sam", "email": "[email protected]"}'
# PUT
curl -X PUT https://api.example.com/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "Sam Updated"}'
# PATCH
curl -X PATCH https://api.example.com/users/1 \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
# DELETE
curl -X DELETE https://api.example.com/users/1
# HEAD (headers only, no body)
curl -I https://example.com
Headers
# Set custom header
curl -H "Authorization: Bearer eyJhbG..." https://api.example.com/me
# Multiple headers
curl -H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: abc123" \
https://api.example.com/data
# User-Agent
curl -A "MyApp/1.0" https://example.com
# Referer
curl -e "https://google.com" https://example.com
POST Data
# JSON body
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"key": "value", "count": 42}'
# JSON from file
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d @payload.json
# Form data (application/x-www-form-urlencoded)
curl -X POST https://example.com/login \
-d "username=sam&password=secret"
# Form data (multipart — for file upload)
curl -X POST https://example.com/upload \
-F "[email protected]" \
-F "description=My photo"
# Multiple files
curl -X POST https://example.com/upload \
-F "[email protected]" \
-F "[email protected]"
# Raw data
curl -X POST https://example.com/api \
-H "Content-Type: text/plain" \
-d "raw text data here"
Authentication
# Basic auth
curl -u username:password https://api.example.com/data
# Bearer token
curl -H "Authorization: Bearer eyJhbGciOiJ..." https://api.example.com/me
# API key in header
curl -H "X-API-Key: your-key-here" https://api.example.com/data
# API key in URL
curl "https://api.example.com/data?api_key=your-key"
# Client certificate
curl --cert client.pem --key client-key.pem https://secure.example.com
Cookies
# Send cookies
curl -b "session=abc123; theme=dark" https://example.com
# Save cookies to file
curl -c cookies.txt https://example.com/login -d "user=sam&pass=secret"
# Use saved cookies
curl -b cookies.txt https://example.com/dashboard
# Save and send (session management)
curl -c cookies.txt -b cookies.txt https://example.com/page
Downloads
# Download file
curl -O https://example.com/file.zip
# Download with custom name
curl -o myfile.zip https://example.com/file.zip
# Resume interrupted download
curl -C - -O https://example.com/large-file.iso
# Download multiple files
curl -O https://example.com/file1.zip -O https://example.com/file2.zip
# Download silently (scripts)
curl -sSL -o file.zip https://example.com/file.zip
# Limit download speed
curl --limit-rate 1M -O https://example.com/large-file.iso
# Show download progress only
curl -# -O https://example.com/file.zip
SSL/TLS
# Ignore SSL errors (self-signed certs — not for production)
curl -k https://self-signed.example.com
# Specify CA bundle
curl --cacert /path/to/ca-bundle.crt https://example.com
# Check SSL certificate details
curl -vI https://example.com 2>&1 | grep -A 6 "Server certificate"
# Force TLS version
curl --tlsv1.2 https://example.com
curl --tlsv1.3 https://example.com
Timeouts and Retries
# Connection timeout (seconds)
curl --connect-timeout 5 https://example.com
# Max time for entire operation
curl --max-time 30 https://example.com
# Retry on failure
curl --retry 3 --retry-delay 2 https://example.com
# Retry on specific errors
curl --retry 3 --retry-connrefused https://example.com
Response Handling
# HTTP status code only
curl -s -o /dev/null -w "%{http_code}" https://example.com
# Response time
curl -s -o /dev/null -w "Time: %{time_total}s\n" https://example.com
# Detailed timing
curl -s -o /dev/null -w "\
DNS: %{time_namelookup}s\n\
Connect: %{time_connect}s\n\
TLS: %{time_appconnect}s\n\
Start: %{time_starttransfer}s\n\
Total: %{time_total}s\n\
Size: %{size_download} bytes\n\
Speed: %{speed_download} bytes/s\n" https://example.com
# Pretty-print JSON response
curl -s https://api.example.com/data | python3 -m json.tool
# Or with jq:
curl -s https://api.example.com/data | jq .
# Extract specific field with jq
curl -s https://api.example.com/users/1 | jq '.name'
Proxy
# HTTP proxy
curl -x http://proxy:8080 https://example.com
# SOCKS5 proxy
curl --socks5 localhost:1080 https://example.com
# SOCKS5 with DNS resolution through proxy
curl --socks5-hostname localhost:1080 https://example.com
# Proxy with authentication
curl -x http://user:pass@proxy:8080 https://example.com
# No proxy for specific hosts
curl --noproxy "localhost,127.0.0.1" https://api.example.com
Useful Patterns
API Health Check Script
status=$(curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health)
if [ "$status" != "200" ]; then
echo "API is down! Status: $status"
fi
Download if Newer
# Only download if server version is newer than local
curl -z local-file.txt -O https://example.com/file.txt
POST JSON and Parse Response
response=$(curl -s -X POST https://api.example.com/auth \
-H "Content-Type: application/json" \
-d '{"username":"sam","password":"secret"}')
token=$(echo "$response" | jq -r '.token')
echo "Token: $token"
Test Multiple URLs
for url in https://example.com https://api.example.com https://cdn.example.com; do
code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
echo "$url: $code"
done
Common Flags Reference
| Flag | What it does |
|---|---|
-s |
Silent (no progress) |
-S |
Show errors even in silent mode |
-L |
Follow redirects |
-v |
Verbose (debug) |
-I |
Headers only (HEAD request) |
-i |
Include headers in output |
-o file |
Save to file |
-O |
Save with original filename |
-d data |
POST data |
-F field=value |
Multipart form data |
-H header |
Set header |
-X METHOD |
Set HTTP method |
-u user:pass |
Basic auth |
-b cookies |
Send cookies |
-c file |
Save cookies |
-k |
Skip SSL verification |
-x proxy |
Use proxy |