curl speaks URLs. It fetches pages, downloads files, and — the reason every developer keeps it open — tests APIs without leaving the terminal.

GET and download #

Fetch a URL and download a file
$ curl https://aospix.com
$ curl -O https://aospix.com/og.jpg

By default curl prints the response body to the terminal. -O saves it under the remote name; -o picks your own.

The flags that matter #

FlagMeaning
-IHeaders only, a HEAD request
-LFollow redirects
-o fileWrite body to a file (-O keeps the remote name)
-H "K: V"Add a request header
-d 'data'Send a request body, which switches to POST
-X METHODChoose GET, PUT, DELETE and friends
-sSilent: no progress bar
-w fmtCustom output after transfer: status, timing

Testing an API #

The classic POST with a JSON body:

POST JSON to an API
$ curl -X POST https://api.example.com/keys \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"name": "laptop", "days": 30}'

Line continuations make the request readable — each header on its own line, exactly like the eventual code will be.

Health checks #

A status code in one line, no body noise:

Check a URL's status code
$ curl -s -o /dev/null -w "%{http_code}\n" https://aospix.com
200

That one-liner is the backbone of uptime scripts and deploy smoke tests. Add -I first when you want to see caching and content-type headers; -L matters whenever the target redirects, such as HTTP to HTTPS or www to apex.

For machine-to-machine transfer over SSH instead of HTTP, see ssh. To inspect what a server actually returned, cat or grep the saved output. More in the journal.