curl: transfer data and test web servers
curl sends requests to servers and shows the answers. Administrators use it to download files, call APIs and, above all, to test web servers from the command line exactly as a browser would reach them.
Download
curl https://example.com/ # print the page
curl -O https://example.com/file.tar.gz # save under the remote name
curl -o latest.tgz https://example.com/dl # save under a name you choose
curl -L -O https://example.com/download # follow redirects
curl -C - -O https://example.com/big.iso # resume an interrupted download
wget https://example.com/file.tar.gz # wget does the same, with resume and recursion built in
Test a web server
curl -I https://www.example.com/ # headers only (HEAD request)
curl -sv https://www.example.com/ -o /dev/null # full conversation, TLS details included
curl -sI http://example.com/ | grep -i location # where does HTTP redirect to?
curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/health
curl --resolve www.example.com:443:203.0.113.20 https://www.example.com/ # test a new server before changing DNS
curl -H 'Host: www.example.com' http://127.0.0.1/ # test a virtual host locally
curl --http2 -sI https://www.example.com/ | head -1 # is HTTP/2 working?
--resolve is the cleanest way to check a site on a new server: it connects to the address you give but uses the real name for TLS and the Host header, so the certificate is checked too.
Measure timing
curl -s -o /dev/null -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} first byte %{time_starttransfer} total %{time_total}\n' https://www.example.com/
APIs: POST, JSON and authentication
curl -d 'name=anna&role=admin' https://api.example.com/users # form POST
curl -H 'Content-Type: application/json' -d '{"name":"anna"}' https://api.example.com/users
curl --json '{"name":"anna"}' https://api.example.com/users # same, curl 7.82+
curl -X DELETE https://api.example.com/users/42
curl -u anna https://example.com/private/ # basic auth, asks for the password
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me
curl -s https://api.example.com/items | jq '.[0]' # pretty-print JSON with jq
Avoid putting passwords and tokens directly on the command line: other users can see them in ps, and they end up in your shell history. Use -u user without the password, a .netrc file, or read headers from a file with -H @file. A shell variable keeps the secret out of your history, but its value still shows in ps.
In scripts
curl -fsSL --retry 3 --max-time 30 https://example.com/data.json -o data.json || exit 1
-f: fail with an error code on HTTP errors (404, 500) instead of saving the error page.-sS: silent, but still show errors.--retryand--max-time: do not hang forever.
Be careful with the popular curl … | sh installers: you run whatever the server sends. Download the script, read it, then run it.
For name resolution problems, see dig.