๐ŸŒ

curl

curl: HTTP requests, authentication, headers, file transfer, and debugging

Basic Requests

GET, POST, PUT, PATCH, DELETE

bashยทGET
curl https://api.example.com/users

# Verbose output (headers + body)
curl -v https://api.example.com/users

# Silent (no progress bar)
curl -s https://api.example.com/users

# Follow redirects
curl -L https://example.com

# Limit redirect depth
curl -L --max-redirs 5 https://example.com
bashยทPOST โ€” JSON body
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice","email":"alice@example.com"}'

# From a file
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d @payload.json
bashยทPUT & PATCH
# PUT (replace)
curl -X PUT https://api.example.com/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice Updated"}'

# PATCH (partial update)
curl -X PATCH https://api.example.com/users/1 \
  -H "Content-Type: application/json" \
  -d '{"email":"new@example.com"}'
bashยทDELETE
curl -X DELETE https://api.example.com/users/1

# With auth header
curl -X DELETE https://api.example.com/users/1 \
  -H "Authorization: Bearer <token>"

Headers & Output

Send and inspect headers, control output format

bashยทSend custom headers
curl https://api.example.com \
  -H "Authorization: Bearer <token>" \
  -H "Accept: application/json" \
  -H "X-Request-ID: abc123"

# Multiple headers with a variable
TOKEN="my-secret"
curl https://api.example.com \
  -H "Authorization: Bearer $TOKEN"
bashยทInspect response headers
# Show only response headers (HEAD request)
curl -I https://example.com

# Show response headers + body
curl -i https://api.example.com/users

# Write headers to a file, body to stdout
curl -D headers.txt https://api.example.com/users
bashยทSave & format output
# Save response to file
curl -o response.json https://api.example.com/users

# Save with remote filename
curl -O https://example.com/file.zip

# Pretty-print JSON (pipe to jq)
curl -s https://api.example.com/users | jq .

# Write only HTTP status code
curl -s -o /dev/null -w "%{http_code}" https://api.example.com/users

Authentication

Basic auth, Bearer tokens, API keys, and client certificates

bashยทBasic auth
# Username + password prompt
curl -u alice https://api.example.com

# Username + password inline (avoid in scripts โ€” leaks in history)
curl -u alice:password https://api.example.com

# Encode manually
curl -H "Authorization: Basic $(echo -n alice:password | base64)" \
  https://api.example.com
bashยทBearer token & API key
# Bearer token
curl -H "Authorization: Bearer eyJhbGci..." https://api.example.com

# API key in header
curl -H "X-API-Key: my-key" https://api.example.com

# API key as query param
curl "https://api.example.com/data?api_key=my-key"
bashยทClient certificates (mTLS)
# Client cert + key
curl --cert client.crt --key client.key https://api.example.com

# PEM bundle (cert + key in one file)
curl --cert bundle.pem https://api.example.com

# Provide a CA cert to verify server
curl --cacert ca.crt https://api.example.com

# Skip TLS verification (testing only โ€” insecure)
curl -k https://self-signed.example.com

Form Data & File Upload

URL-encoded forms, multipart uploads, and binary files

bashยทURL-encoded form
# Shorthand POST with form data
curl -d "username=alice&password=secret" https://example.com/login

# Explicit content-type
curl -X POST https://example.com/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "username=alice jones" \
  --data-urlencode "password=secret"
bashยทMultipart file upload
# Upload a single file
curl -X POST https://api.example.com/upload \
  -F "file=@photo.jpg"

# With extra form fields
curl -X POST https://api.example.com/upload \
  -F "file=@photo.jpg;type=image/jpeg" \
  -F "title=My Photo" \
  -F "public=true"

# Upload multiple files
curl -X POST https://api.example.com/batch \
  -F "files[]=@file1.txt" \
  -F "files[]=@file2.txt"

Query Params & URLs

Build URLs, encode params, and use variables

bashยทQuery string
# Inline query string
curl "https://api.example.com/search?q=curl&limit=10&page=2"

# URL-encode individual params
curl -G https://api.example.com/search \
  --data-urlencode "q=hello world" \
  --data-urlencode "limit=10"
bashยทURL globbing (batch requests)
# Fetch multiple pages
curl "https://api.example.com/page/[1-5]"

# Fetch multiple endpoints
curl "https://api.example.com/{users,posts,comments}"

# Disable globbing if URL contains braces
curl -g "https://api.example.com/data{json}"

Cookies

Send, save, and load cookies

bashยทSend & persist cookies
# Send a cookie manually
curl -H "Cookie: session=abc123" https://example.com/dashboard

# Save cookies to a jar file
curl -c cookies.txt https://example.com/login \
  -d "user=alice&pass=secret"

# Load cookies from jar and save updates
curl -b cookies.txt -c cookies.txt https://example.com/dashboard

# One-liner: log in then use session
curl -s -c cookies.txt -X POST https://example.com/login \
  -d "user=alice&pass=secret" && \
curl -s -b cookies.txt https://example.com/profile

Timeouts & Retries

Control connection timeouts and automatic retries

bashยทTimeouts
# Max time for the whole operation (seconds)
curl --max-time 10 https://api.example.com

# Connection timeout only
curl --connect-timeout 5 https://api.example.com

# Both
curl --connect-timeout 5 --max-time 30 https://api.example.com
bashยทRetries
# Retry on transient errors (up to 3 times)
curl --retry 3 https://api.example.com

# Retry with delay between attempts (seconds)
curl --retry 3 --retry-delay 2 https://api.example.com

# Retry on all errors including HTTP 5xx
curl --retry 3 --retry-all-errors https://api.example.com

# Retry with exponential backoff
curl --retry 5 --retry-delay 1 --retry-max-time 60 https://api.example.com

Proxy & Tunneling

Route requests through HTTP, HTTPS, and SOCKS proxies

bashยทProxy settings
# HTTP proxy
curl -x http://proxy.example.com:8080 https://api.example.com

# SOCKS5 proxy
curl --socks5 127.0.0.1:1080 https://api.example.com

# Proxy with credentials
curl -x http://user:pass@proxy.example.com:8080 https://api.example.com

# Bypass proxy for specific hosts
curl --noproxy "localhost,internal.corp" -x http://proxy:8080 https://api.example.com

# Use environment variable
export https_proxy=http://proxy.example.com:8080
curl https://api.example.com

Debugging

Verbose output, timing, and trace options

bashยทVerbose & trace
# Verbose: shows request/response headers
curl -v https://api.example.com

# Extra verbose: also shows SSL handshake
curl -vv https://api.example.com

# Full wire trace (writes to stderr)
curl --trace - https://api.example.com

# Trace to a file
curl --trace trace.txt https://api.example.com
bashยทTiming breakdown
curl -s -o /dev/null -w "
    DNS lookup:     %{time_namelookup}s
    TCP connect:    %{time_connect}s
    TLS handshake:  %{time_appconnect}s
    TTFB:           %{time_starttransfer}s
    Total:          %{time_total}s
    HTTP status:    %{http_code}
    Downloaded:     %{size_download} bytes
" https://api.example.com
bashยทDry-run & config
# Print the request curl would send, without sending it
curl --dry-run -X POST https://api.example.com \
  -H "Content-Type: application/json" \
  -d '{"key":"value"}'

# Load options from a config file (.curlrc)
curl --config my.curlrc https://api.example.com

# Sample .curlrc
# header = "Authorization: Bearer mytoken"
# silent
# max-time = 30

File Download

Download files, resume interrupted transfers, and limit speed

bashยทDownload files
# Save with a custom name
curl -o archive.tar.gz https://example.com/releases/v1.0.tar.gz

# Save with the remote filename
curl -O https://example.com/releases/v1.0.tar.gz

# Download multiple files
curl -O https://example.com/file1.zip \
     -O https://example.com/file2.zip

# Show progress bar
curl --progress-bar -O https://example.com/large.iso
bashยทResume & speed
# Resume an interrupted download
curl -C - -O https://example.com/large.iso

# Limit download speed (bytes per second; k/m suffixes supported)
curl --limit-rate 500k -O https://example.com/large.iso

# Check remote file size without downloading
curl -sI https://example.com/large.iso | grep -i content-length