curl Command Examples for Linux: A Practical Reference
The most useful curl commands for developers — GET, POST, headers, auth, file downloads, timing requests, and debugging HTTP APIs from the terminal.
curl transfers data to and from URLs. Every developer uses it to test APIs, download files, and debug HTTP — but most people only know curl https://example.com. This is the reference for the flags you will actually reach for.
GET request
curl https://api.example.com/users
Add -s to suppress the progress meter (useful in scripts):
curl -s https://api.example.com/users
POST with JSON
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}'
-H sets a request header. -d sends the data as the request body. When -d is set, curl uses POST automatically — -X POST is technically redundant but makes the intent explicit.
Authentication
Bearer token:
curl https://api.example.com/users \
-H "Authorization: Bearer eyJhbGci..."
Basic auth:
curl -u admin:secretpassword https://api.example.com/admin
-u user:pass sends a Authorization: Basic header with the credentials base64-encoded. Use Base64 Encoder if you need to inspect or construct the value manually.
API key as a header:
curl https://api.example.com/data \
-H "X-API-Key: your-api-key-here"
Show response headers
curl -I https://example.com
-I sends a HEAD request — response headers only, no body. To show headers alongside the body:
curl -v https://example.com
-v (verbose) prints the full request/response exchange: headers sent, headers received, TLS handshake details. Invaluable for debugging.
For a cleaner output that separates headers from body:
curl -D - https://example.com
-D - dumps response headers to stdout, then the body follows.
Follow redirects
curl -L https://example.com
-L follows 301/302 redirects. Without it, curl stops at the redirect and returns the redirect response.
Save output to a file
curl -o output.html https://example.com
Download a file and keep the remote filename:
curl -O https://example.com/files/archive.tar.gz
Resume an interrupted download:
curl -C - -O https://example.com/files/large-file.iso
Upload a file
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/local/file.txt"
-F sends a multipart/form-data request. @ prefix tells curl to read from a file path rather than treating the value as a literal string.
PUT and PATCH requests
curl -X PUT https://api.example.com/users/42 \
-H "Content-Type: application/json" \
-d '{"name": "Alice Updated"}'
curl -X PATCH https://api.example.com/users/42 \
-H "Content-Type: application/json" \
-d '{"email": "new@example.com"}'
DELETE request
curl -X DELETE https://api.example.com/users/42 \
-H "Authorization: Bearer eyJhbGci..."
Send multiple headers
curl https://api.example.com/data \
-H "Authorization: Bearer token123" \
-H "Accept: application/json" \
-H "X-Request-ID: abc-123"
Measure request timing
curl -o /dev/null -s -w "
dns_resolution: %{time_namelookup}s
tcp_connect: %{time_connect}s
tls_handshake: %{time_appconnect}s
ttfb: %{time_starttransfer}s
total: %{time_total}s
http_code: %{http_code}
" https://example.com
This is the fastest way to profile where a request is spending time without installing extra tools. TTFB (time to first byte) is the most useful single number for backend latency.
Set a timeout
curl --max-time 10 https://api.example.com/slow-endpoint
--max-time is the total allowed time in seconds. --connect-timeout limits only the initial connection:
curl --connect-timeout 5 --max-time 30 https://api.example.com/
Ignore SSL certificate errors
For testing self-signed certificates in development only — never use this in production scripts:
curl -k https://localhost:8443
For the correct approach to generating self-signed certificates for local development, see the Self-Signed SSL tutorial.
Use a config file for repetitive flags
If you are hitting the same API repeatedly, put shared flags in a config file:
# ~/.curl/myapi
-H "Authorization: Bearer token123"
-H "Content-Type: application/json"
curl -K ~/.curl/myapi https://api.example.com/users
Format JSON output
curl does not pretty-print JSON. Pipe to jq:
curl -s https://api.example.com/users | jq .
curl -s https://api.example.com/users | jq '.[0].email'
Decode a JWT from a curl response
curl -s https://api.example.com/auth/login \
-X POST \
-H "Content-Type: application/json" \
-d '{"user":"alice","pass":"secret"}' \
| jq -r '.token'
Pipe that token into the JWT Decoder to inspect the claims without writing a script.
SysEmperor