Some CDN link just handed you a 200-byte HTML file instead of the zip. We've been there, and the fix is one letter: curl -LO follows the redirect to the real file, while plain curl -O saves whatever the URL points at, under its own name. For APIs, curl -i https://api.example.com prints the status line and headers with the body, which is what you actually want when an endpoint returns the wrong thing. curl ships with macOS, Linux and Windows 10 and 11, so there's nothing to install. Below we cover clean downloads and a POST with a JSON body, then the handful of flags (-s, -L, -H, -d) we keep reaching for.
The short answer
curl -O url downloads to a file and curl -L follows redirects. For API
testing, curl -i url shows the headers with the body. Send JSON with
-X POST -H and -d. Built into macOS, Linux and Windows.
Download a file
curl -O https://example.com/report.pdf That drops report.pdf into the current folder. Want a different name on the
way down? Lowercase -o. And if the link redirects (most do), add -L;
honestly I forget it exists until a download comes back as a tiny HTML file:
curl -LO https://example.com/file.zip Test an API
curl -i https://api.example.com/health -i prints the status line and headers above the body, so you see the 200
(or the 500) and the content type instead of just the JSON. Headers only?
Capital -I.
Send a POST with a JSON body
curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' https://api.example.com/items -H sets the content type so the server parses the body as JSON, and -d
carries it. Drop the -X POST and curl still POSTs. -d implies it.
The flags you’ll actually reuse
Not many. -O or -o to save, -L to follow redirects, -i or -I for
headers, -H to set one, -d to send a body, and -s to silence the progress
meter in scripts. That’s the whole working set. When we want to grade the
headers a site sends back without memorizing them, our
HTTP headers checker does it visually.
Frequently asked questions
What is the difference between curl -O and curl -o?
Capital -O keeps the name the file has on the server. Lowercase -o lets you pick one: "curl -o report.pdf https://example.com/r". Pass neither and curl dumps the file straight to your screen, which is a mess for anything binary.
My download saved a tiny HTML file instead of the real one. Why?
The URL redirected, and curl saved the redirect page itself. Add -L so it follows through to the final file: "curl -LO https://example.com/file.zip". Most CDN links and shortened URLs won't work without it.
How do I send a POST request with JSON?
Set the header with -H and the body with -d, like "curl -X POST -H header -d data url". curl switches to POST the moment it sees -d, so -X POST is technically optional, but we write it anyway; the intent reads better.
How do I see only the response headers?
-I (capital i) sends a HEAD request and prints headers only. Lowercase -i prints headers plus the body. We use -I to check a status code or a redirect without pulling down the whole file.