M
MeshWorld.
Cheatsheet curl API Terminal Linux HTTP Developer Tools REST 7 min read

curl Cheat Sheet: API Testing, Auth & File Upload

By Vishnu Damwala

Quick reference tables

Basic requests

CommandWhat it does
curl https://example.comGET request, print body
curl -o file.html https://example.comSave response to file
curl -O https://example.com/file.zipSave with original filename
curl -L https://example.comFollow redirects
curl -s https://example.comSilent (no progress bar)
curl -S https://example.comShow errors even when silent
curl -v https://example.comVerbose — show all headers
curl --trace - https://example.comFull hex dump of all traffic

Headers

CommandWhat it does
curl -I https://example.comHEAD request — headers only
curl -i https://example.comInclude 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

CommandWhat it does
curl -X POST https://api.example.comPOST with no body
curl -d "key=value" https://api.example.comPOST form data
curl -d '{"name":"Alice"}' -H "Content-Type: application/json" urlPOST JSON
curl --data-urlencode "name=Alice Smith" urlURL-encode data
curl -d @data.json -H "Content-Type: application/json" urlPOST from file
curl -X PUT -d '{}' urlPUT request
curl -X PATCH -d '{}' urlPATCH request
curl -X DELETE urlDELETE request

Authentication

CommandWhat it does
curl -u user:password urlBasic auth
curl -H "Authorization: Bearer TOKEN" urlBearer token
curl -H "Authorization: Basic BASE64" urlBasic auth manually
curl --oauth2-bearer TOKEN urlOAuth2 bearer
curl --cert cert.pem --key key.pem urlClient certificate auth
curl --cacert ca.pem urlCustom CA certificate
curl -k urlSkip SSL verification (dev only)

File upload

CommandWhat it does
curl -F "file=@photo.jpg" urlUpload file (multipart)
curl -F "file=@photo.jpg;type=image/jpeg" urlUpload with MIME type
curl -F "file=@file.txt" -F "name=Alice" urlUpload file + form field
curl -T file.txt urlPUT upload (FTP-style)
curl --data-binary @file.bin urlBinary POST

Response control

CommandWhat it does
curl -w "%{http_code}" urlPrint only status code
curl -w "%{time_total}" urlPrint total request time
curl -D headers.txt urlSave headers to file
curl -D - urlPrint headers to stdout
curl --max-time 10 urlTimeout after 10 seconds
curl --connect-timeout 5 urlConnection timeout
curl --retry 3 urlRetry on failure
curl --retry-delay 2 urlDelay between retries
curl -r 0-1023 urlDownload only first 1024 bytes

Cookies

CommandWhat it does
curl -c cookies.txt urlSave cookies to file
curl -b cookies.txt urlSend cookies from file
curl -b "session=abc123" urlSend cookie string
curl -c cookies.txt -b cookies.txt urlSave and send cookies

Proxy

CommandWhat it does
curl -x http://proxy:8080 urlUse HTTP proxy
curl -x socks5://localhost:1080 urlUse SOCKS5 proxy
curl --noproxy "localhost,127.0.0.1" urlBypass 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":"bob@example.com"}'
api_call DELETE /users/42

curl vs wget — when to use which

Taskcurlwget
API testingcurl -X POST ...awkward
Download a fileboth workwget url is simpler
Resume downloadcurl -C -wget -c
Mirror a websitenot idealwget -r
Scripting/pipinggreatless flexible
Send headers-H--header
Quiet mode-s-q