REST (Representational State Transfer) is the dominant API architecture. Resources are identified by URLs, actions by HTTP methods. curl is the universal tool for testing APIs from the command line.
| Item | Syntax / Value | Description |
|---|---|---|
| curl -X | curl -X POST url | Specify HTTP method |
| curl -H | curl -H 'Content-Type: application/json' | Set request header |
| curl -d | curl -d '{"key":"value"}' | Set request body (implies POST) |
| curl --data-raw | curl --data-raw 'key=value&key2=value2' | URL-encoded form data |
| curl -o | curl -o output.html https://example.com/ | Save response to file |
| curl -O | curl -O https://example.com/file.tar.gz | Save with remote filename |
| curl -L | curl -L https://example.com/ | Follow redirects |
| curl -s | curl -s url | Silent mode — no progress bar |
| curl -v | curl -v url | Verbose — show all headers |
| curl -I | curl -I url | HEAD request — headers only |
| curl -u | curl -u user:pass url | Basic authentication |
| curl -k | curl -k https://self-signed.local/ | Skip TLS certificate verification (insecure!) |
| curl --retry | curl --retry 3 --retry-delay 2 url | Retry on failure |
| curl -w | curl -w '%{http_code}' -o /dev/null -s url | Get HTTP status code only |
| curl -c | curl -c cookies.txt url | Save cookies to file |
| curl -b | curl -b cookies.txt url | Send cookies from file |
| curl --compressed | curl --compressed url | Request gzip compression |
| curl -F | curl -F 'file=@photo.jpg' -F 'name=Alice' url | Multipart form upload |
| curl --resolve | curl --resolve example.com:443:1.2.3.4 https://example.com/ | Override DNS for testing |
| wget | wget https://example.com/file.tar.gz | Download file |
| wget -r | wget -r --no-parent https://example.com/docs/ | Recursive download |
| wget -q | wget -q -O output.html url | Quiet mode, specify output file |
| wget --limit-rate | wget --limit-rate=1m url | Limit download speed |
| REST: GET collection | GET /api/courses | List all courses |
| REST: GET item | GET /api/courses/42 | Get course with ID 42 |
| REST: POST | POST /api/courses {body} | Create new course |
| REST: PUT | PUT /api/courses/42 {body} | Replace course 42 |
| REST: PATCH | PATCH /api/courses/42 {body} | Update fields of course 42 |
| REST: DELETE | DELETE /api/courses/42 | Delete course 42 |
| Bearer token | Authorization: Bearer eyJhbGci... | JWT or OAuth2 token authentication |
| API key header | X-API-Key: myapikey123 | API key in custom header |
| Rate limiting | Retry-After: 60 / X-RateLimit-Remaining: 42 | Headers indicating rate limit status |
| Pagination | ?page=2&per_page=20 / Link: <url>; rel=next | Common API pagination patterns |
# curl API reference — essential patterns
# ── REST API operations ───────────────────────────────────────
BASE="https://jsonplaceholder.typicode.com"
# GET — list resources
curl -s "$BASE/posts" | python3 -m json.tool | head -30
# GET — single resource
curl -s "$BASE/posts/1" | python3 -m json.tool
# GET with query params
curl -s "$BASE/posts?userId=1" | python3 -c 'import json,sys; posts=json.load(sys.stdin); print(f"{len(posts)} posts")'
# POST — create
curl -s -X POST "$BASE/posts" \
-H "Content-Type: application/json" \
-d '{"title":"MyWebUniversity","body":"Free education for all","userId":1}' \
| python3 -m json.tool
# PUT — full replace
curl -s -X PUT "$BASE/posts/1" \
-H "Content-Type: application/json" \
-d '{"id":1,"title":"Updated Title","body":"Updated body","userId":1}' \
| python3 -m json.tool
# PATCH — partial update
curl -s -X PATCH "$BASE/posts/1" \
-H "Content-Type: application/json" \
-d '{"title":"Just title changed"}' \
| python3 -m json.tool
# DELETE
curl -s -X DELETE "$BASE/posts/1" -w "HTTP %{http_code}\n"
# ── Authentication patterns ───────────────────────────────────
# Bearer token (OAuth2 / JWT)
curl -s -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
https://api.example.com/profile
# API key in header
curl -s -H "X-API-Key: myapikey123" https://api.example.com/data
# API key in query param (less secure)
curl -s "https://api.example.com/data?api_key=myapikey123"
# Basic auth (username:password)
curl -s -u "alice:password123" https://api.example.com/admin/
# Get token first, then use it
TOKEN=$(curl -s -X POST https://api.example.com/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret"}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])')
curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/profile
# ── Useful curl patterns ──────────────────────────────────────
# Get only HTTP status code
curl -s -o /dev/null -w "%{http_code}" https://www.mywebuniversity.com/
# Output: 200
# Time the request
curl -s -o /dev/null -w "Connect: %{time_connect}s Total: %{time_total}s" \
https://www.mywebuniversity.com/
# Download and extract in one command
curl -L https://github.com/user/repo/archive/main.tar.gz | tar xz
# Upload file (multipart form)
curl -F "file=@report.pdf" -F "title=Annual Report" \
https://api.example.com/upload
# Retry with exponential backoff
curl --retry 5 --retry-delay 2 --retry-max-time 60 \
https://api.example.com/data
# Save cookies and send in next request
curl -c /tmp/cookies.txt -b /tmp/cookies.txt \
-d "username=alice&password=secret" \
https://example.com/login
# ── wget ─────────────────────────────────────────────────────
# Download single file
wget https://example.com/file.tar.gz
# Resume interrupted download
wget -c https://example.com/large-file.tar.gz
# Mirror a website section
wget -r -l 2 --no-parent -P ./mirror/ https://www.mywebuniversity.com/chapter-1.html
# Download quietly, save as specific filename
wget -q -O chapter42.html https://www.mywebuniversity.com/chapter-42.html← SSH & SCP & SFTP | 🏠 Index | Identity & Access Management →