Skip to content

curl Command Cheat Sheet

curl (Client URL) is a command-line tool for transferring data with URLs. It supports numerous protocols including HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, and more. It's the go-to tool for API testing, debugging web services, and automated file transfers.


Synopsis

curl [OPTIONS] [URL...]

Description

curl is a tool for working with URLs. Unlike wget (which is better for recursive downloads), curl excels at API interactions, supports more protocols, can upload data, and outputs to stdout by default. It's widely used in scripts and CI/CD pipelines.


Basic Usage

Fetch Web Page

curl https://example.com

Outputs page content to stdout.

Save to File with -o

curl -o filename.html https://example.com
curl -o /path/to/file.zip https://example.com/file.zip

Save with Original Filename -O

curl -O https://example.com/file.zip

Uses the filename from URL.

Download Multiple Files

curl -O https://example.com/file1.zip -O https://example.com/file2.zip

HTTP Methods

GET (Default)

curl https://api.example.com/users
curl -X GET https://api.example.com/users  # Explicit

POST

curl -X POST https://api.example.com/users
curl --request POST https://api.example.com/users

PUT

curl -X PUT https://api.example.com/users/123

DELETE

curl -X DELETE https://api.example.com/users/123

PATCH

curl -X PATCH https://api.example.com/users/123
curl -I https://example.com  # Show headers only
curl --head https://example.com

Sending Data

POST Form Data

curl -d "name=John&age=30" https://example.com/form
curl --data "param1=value1&param2=value2" https://api.example.com/endpoint

POST JSON

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"name":"John","age":30}' \
  https://api.example.com/users

POST from File

curl -d @data.json https://api.example.com/endpoint
curl --data-binary @file.json https://api.example.com/upload

URL-encoded POST

curl --data-urlencode "name=John Doe" https://example.com/api

PUT with Data

curl -X PUT \
  -H "Content-Type: application/json" \
  -d '{"name":"Updated Name"}' \
  https://api.example.com/users/123

Headers

Add Custom Header

curl -H "Authorization: Bearer TOKEN" https://api.example.com/data
curl --header "Accept: application/json" https://api.example.com/data

Multiple Headers

curl -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     https://api.example.com/data

Show Response Headers

curl -i https://example.com         # Include headers in output
curl -I https://example.com         # Headers only (HEAD request)
curl --include https://example.com  # Include headers

Save Headers to File

curl -D headers.txt https://example.com
curl --dump-header headers.txt https://example.com

Verbose Output (Show Request + Response)

curl -v https://example.com
curl --verbose https://example.com

Shows complete request/response including headers.


Authentication

Basic Authentication

curl -u username:password https://example.com/api
curl --user username:password https://api.example.com/data

Prompt for Password

curl -u username https://example.com/api
# Prompts for password

Bearer Token

curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/data

API Key

curl -H "X-API-Key: YOUR_API_KEY" https://api.example.com/data

OAuth 2.0

curl -H "Authorization: Bearer ACCESS_TOKEN" https://api.example.com/resource

Cookies

curl -b "session=abc123" https://example.com
curl --cookie "name=value" https://example.com

Save Cookies to File

curl -c cookies.txt https://example.com/login
curl --cookie-jar cookies.txt https://example.com/login

Load Cookies from File

curl -b cookies.txt https://example.com/profile
curl --cookie cookies.txt https://example.com/dashboard
# Login and save session
curl -c cookies.txt \
     -d "username=user&password=pass" \
     https://example.com/login

# Use saved session
curl -b cookies.txt https://example.com/dashboard

File Upload

Upload Single File

curl -F "file=@document.pdf" https://example.com/upload
curl --form "file=@image.jpg" https://example.com/api/images

Multiple Files

curl -F "file1=@doc.pdf" -F "file2=@image.jpg" https://example.com/upload

With Additional Fields

curl -F "file=@report.pdf" \
     -F "title=Monthly Report" \
     -F "category=finance" \
     https://example.com/upload

Upload with Custom Filename

curl -F "file=@local.txt;filename=remote.txt" https://example.com/upload

Specify Content-Type

curl -F "file=@data.json;type=application/json" https://example.com/api

Download Options

Follow Redirects

curl -L https://short.url
curl --location https://bit.ly/abc123

Resume Download

curl -C - -O https://example.com/largefile.iso
curl --continue-at - -O https://example.com/file.zip

Limit Download Rate

curl --limit-rate 100K https://example.com/file.zip
curl --limit-rate 1M https://example.com/large.iso

Timeout

curl --max-time 30 https://example.com
curl --connect-timeout 10 https://example.com

Download Range

# First 1000 bytes
curl -r 0-999 https://example.com/file.bin

# From byte 1000 onward
curl -r 1000- https://example.com/file.bin

Output Control

Silent Mode

curl -s https://example.com
curl --silent https://api.example.com/data

Show Errors Only

curl -sS https://example.com
curl --silent --show-error https://api.example.com

Progress Bar

curl -# -O https://example.com/file.zip
curl --progress-bar -O https://example.com/download

Output to /dev/null

curl -o /dev/null https://example.com

Useful for testing without saving output.


SSL/TLS

Ignore SSL Certificate Errors

curl -k https://self-signed.example.com
curl --insecure https://expired-cert.example.com

Warning: Use only for testing!

Specify CA Certificate

curl --cacert /path/to/ca-cert.pem https://example.com

Client Certificate

curl --cert client.pem --key client-key.pem https://secure.example.com

Specify TLS Version

curl --tlsv1.2 https://example.com
curl --tls-max 1.2 https://api.example.com

Proxy

HTTP Proxy

curl -x http://proxy.example.com:8080 https://api.example.com
curl --proxy http://proxy:8080 https://example.com

SOCKS Proxy

curl --socks5 localhost:1080 https://example.com

Proxy with Authentication

curl -x http://proxy:8080 -U user:pass https://example.com
curl --proxy-user user:pass --proxy http://proxy:8080 https://api.example.com

No Proxy for Specific Hosts

curl --noproxy localhost,127.0.0.1 https://example.com

Advanced Features

Custom User-Agent

curl -A "Mozilla/5.0" https://example.com
curl --user-agent "MyBot/1.0" https://api.example.com

Referrer

curl -e "https://google.com" https://example.com
curl --referer "https://previous-site.com" https://target.com

Compressed Response

curl --compressed https://example.com

Requests gzip/deflate compression.

Keep-Alive

curl --keepalive-time 60 https://example.com

IPv4 or IPv6 Only

curl -4 https://example.com  # IPv4 only
curl -6 https://example.com  # IPv6 only

Resolve Host to IP

curl --resolve example.com:443:1.2.3.4 https://example.com

Write Out Stats

curl -w "HTTP Status: %{http_code}\nTotal Time: %{time_total}s\n" https://example.com

Common variables: - %{http_code} - HTTP status code - %{time_total} - Total time - %{speed_download} - Download speed - %{size_download} - Downloaded size - %{content_type} - Content-Type


Practical Examples

API Testing

# GET request
curl -X GET https://api.github.com/users/octocat

# POST with JSON
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"username":"test","email":"test@example.com"}' \
  https://api.example.com/register

# With authentication
curl -H "Authorization: Bearer $TOKEN" \
  https://api.example.com/protected

Download File Silently

curl -sS -O https://example.com/file.zip

Check Website Status

curl -sI https://example.com | grep HTTP/
# Or get status code only
curl -s -o /dev/null -w "%{http_code}" https://example.com

Download with Progress and Resume

curl -# -C - -O https://releases.ubuntu.com/22.04/ubuntu-22.04-desktop-amd64.iso

Web Scraping

# Get page title
curl -s https://example.com | grep -oP '(?<=<title>).*?(?=</title>)'

# Extract links
curl -s https://example.com | grep -oP 'href="\K[^"]*'

Test REST API

# Create
curl -X POST -H "Content-Type: application/json" \
  -d '{"name":"Item1"}' \
  https://api.example.com/items

# Read
curl https://api.example.com/items/1

# Update
curl -X PUT -H "Content-Type: application/json" \
  -d '{"name":"Updated Item"}' \
  https://api.example.com/items/1

# Delete
curl -X DELETE https://api.example.com/items/1

Debug API Call

curl -v -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"key":"value"}' \
  https://api.example.com/endpoint 2>&1 | tee debug.log

Check Response Time

curl -w "@-" -o /dev/null -s https://example.com <<'EOF'
    time_namelookup:  %{time_namelookup}s\n
       time_connect:  %{time_connect}s\n
    time_appconnect:  %{time_appconnect}s\n
   time_pretransfer:  %{time_pretransfer}s\n
      time_redirect:  %{time_redirect}s\n
 time_starttransfer:  %{time_starttransfer}s\n
                    ----------\n
         time_total:  %{time_total}s\n
EOF

GraphQL Query

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"query":"query { users { id name } }"}' \
  https://api.example.com/graphql

Send Email Data (SMTP)

curl smtp://smtp.example.com \
  --mail-from sender@example.com \
  --mail-rcpt recipient@example.com \
  --upload-file email.txt

Comparison: curl vs wget

Feature curl wget
Default output stdout Save to file
Upload data
HTTP methods All (POST, PUT, DELETE, etc.) GET only
Protocols 25+ protocols HTTP, HTTPS, FTP
Recursive download
Resume download
API testing ✓ Excellent ✗ Limited
Library libcurl None
Cookie handling
Authentication Multiple methods Basic, certificate

Use curl for: API testing, uploads, complex HTTP requests, scripting
Use wget for: Downloading files, mirroring websites, recursive downloads


Common Options Summary

Option Description
-o FILE Save output to file
-O Save with remote filename
-X METHOD HTTP method (GET, POST, etc.)
-d DATA Send POST data
-H HEADER Add custom header
-u USER:PASS Basic authentication
-b COOKIE Send cookie
-c FILE Save cookies
-F NAME=@FILE Upload file
-L Follow redirects
-i Include response headers
-I Show headers only (HEAD request)
-v Verbose mode
-s Silent mode
-# Progress bar
-k Ignore SSL errors
-x PROXY Use proxy
-A AGENT Set User-Agent
-e URL Set Referer
-w FORMAT Output format
--compressed Request compressed response
-C OFFSET Resume download from offset
--limit-rate Limit transfer speed
--max-time Maximum transfer time

Exit Status

Code Meaning
0 Success
1 Unsupported protocol
2 Failed to initialize
3 URL malformed
5 Couldn't resolve proxy
6 Couldn't resolve host
7 Failed to connect
22 HTTP error (status >= 400)
23 Write error
26 Read error
28 Timeout
35 SSL/TLS handshake error
52 Empty reply from server
56 Network data receive error
60 SSL certificate problem

Tips and Best Practices

  1. Use -s in scripts - Silent mode prevents unwanted output
  2. Always follow redirects - Use -L for shortened URLs
  3. Check exit status - $? indicates success/failure
  4. Use -v for debugging - See complete request/response
  5. Save credentials externally - Don't put passwords in command line
  6. Use -w for metrics - Monitor API performance
  7. Combine with jq - Parse JSON responses: curl ... | jq
  8. Use config files - ~/.curlrc for default options
  9. Test with httpbin.org - Great for testing HTTP requests
  10. Use -o /dev/null - When testing, don't save output

~/.curlrc Configuration

# Default options
user-agent = "Mozilla/5.0 (compatible; MyCurlScript/1.0)"
referer = ";auto"
connect-timeout = 60
max-time = 180
retry = 3
retry-delay = 2

# Always follow redirects
location

# Show errors
show-error

# Use compression
compressed