curl & HTTP Clients
Overview
curl is the Swiss Army knife for HTTP from the terminal — installed on virtually every Unix system and available on Windows. It's indispensable for testing APIs, debugging requests, and scripting HTTP interactions.
curl vs wget vs HTTPie
| Feature | curl | wget | HTTPie |
|---|---|---|---|
| Primary use | Flexible HTTP client | File download | Human-friendly HTTP |
| Protocols | HTTP/S, FTP, SCP, SSH, SMTP, etc. | HTTP/S + FTP | HTTP/S only |
| Output | stdout by default | File by default | Formatted + colored |
| JSON | Manual -H + -d | Not built-in | Native with := syntax |
| Install | Pre-installed on most systems | Pre-installed on most Linux | pip install httpie |
curl Essentials
GET
bash
curl https://api.example.com/users
GET with headers
bash
curl -H "Authorization: Bearer TOKEN" https://api.example.com/users
POST JSON
bash
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"Alice"}' https://api.example.com/users
PUT
bash
curl -X PUT -H "Content-Type: application/json" \
-d '{"name":"Bob"}' https://api.example.com/users/1
DELETE
bash
curl -X DELETE https://api.example.com/users/1
Show response headers
bash
curl -i https://api.example.com/users # Headers + body curl -I https://api.example.com/users # HEAD only (headers only)
Follow redirects
bash
curl -L https://api.example.com/old-endpoint
Verbose output
bash
curl -v https://api.example.com/users
Save to file
bash
curl -o file.json https://api.example.com/users # Custom filename curl -O https://example.com/report.pdf # Use remote filename
Basic auth
bash
curl -u user:password https://api.example.com/admin
Form upload
bash
curl -F "file=@photo.jpg" https://api.example.com/upload
Timeout
bash
curl --connect-timeout 5 --max-time 30 https://api.example.com/slow-endpoint
Silent mode (for scripting)
bash
curl -s https://api.example.com/users | jq .
HTTPie
HTTPie provides the same capabilities with a more readable syntax:
GET
bash
http GET api.example.com/users
POST JSON
bash
http POST api.example.com/users name=Alice email=alice@example.com
Bearer auth
bash
http GET api.example.com/users "Authorization:Bearer TOKEN"
Form upload
bash
http -f POST api.example.com/upload file@photo.jpg
Common Patterns
Piping to jq
bash
curl -s https://api.example.com/users | jq '.[].name'
Testing response codes
bash
curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health
Downloading files with progress
bash
curl -# -O https://example.com/file.zip
Sending data from file
bash
curl -d @data.json -H "Content-Type: application/json" https://api.example.com/import
Cookie handling
bash
curl -c cookies.txt -b cookies.txt https://example.com/login
wget
wget excels at file downloading where curl excels at HTTP flexibility.
Recursive download
bash
wget -r https://example.com/docs/
Mirror a site
bash
wget --mirror --convert-links --adjust-extension --page-requisites https://example.com
Resume broken downloads
bash
wget -c https://example.com/large-file.iso
When to prefer wget over curl
- •Downloading large files (automatic retry, resume support)
- •Mirroring or recursive download of websites
- •Downloading when you want file output by default
- •Situations where simplicity of
wget URLis sufficient
Best Practices
- •Use
-sand pipe tojqfor scripted API calls — avoid parsing raw output with grep - •Always set timeouts (
--connect-timeoutand--max-time) in scripts to prevent hanging - •Use HTTPie for interactive API exploration — its colored, formatted output is easier to read
- •Prefer curl for scripting and CI — it is more universally available and predictable
- •Use
-wformat strings for response inspection in scripts (status codes, timing, sizes) - •Store auth tokens in environment variables, not directly on the command line (avoid shell history exposure)