Making requests with curl
Key takeaways
curl sends HTTP by hand from the shell, so you can test
an API or a site without a browser. Fetch a page with curl URL; read the response
with headers (-I) or verbose -v; and shape a request with
-X (method), -d (data), and -H (headers). Add -L to follow redirects
and -o to save. It turns any web request into something you can repeat, script,
and inspect.
A browser hides the request behind a click. curl does the opposite: it makes the exact request visible and puts every part of it under your control. That is precisely what you want when something is misbehaving and you need to know what the server actually said.
The basic request
Give curl a URL and it fetches the response body and prints it:
curl https://example.com
That is the whole “hello world” of curl — it fires off a GET request and dumps the
returned HTML (or JSON, or whatever) to your terminal. When you pass a large file or hit
a slow server, curl draws a progress meter that clutters the output; add -s (silent) to
quiet it:
curl -s https://example.com/api/status
Seeing the response
The body is only half the story. The status code and headers tell you whether the request worked and how the server wants you to treat the answer. curl exposes them with three flags:
-I— fetch the headers only, no body. Perfect for a quick “is it up, and what status does it return?” check.-i— print the headers and the body, headers first.-v— verbose: show the whole exchange, including the request curl sent, the TLS handshake, and every response header.
curl -I https://example.com
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 1256
Reach for -v when a request fails for no obvious reason — it reveals redirects, header
mistakes, and TLS problems that -I alone would hide.
Sending data
To do more than read, change the method and attach a body. -X sets the method and -d
carries the data:
curl -X POST -d 'name=matt&system=P25' https://example.com/register
For a JSON API, send the JSON as the body and tell the server how to read it with a
Content-Type header via -H:
curl -X POST \
-H 'Content-Type: application/json' \
-d '{"name":"matt","system":"P25"}' \
https://example.com/api/register
-H also carries authentication, such as an API token:
curl -H 'Authorization: Bearer TOKEN' https://example.com/api/private
Keep secrets in headers, never in the URL — URLs end up in logs, browser history, and
Referer headers, so a token in the query string leaks. This request/response shaping is
exactly how you exercise a REST API by hand.
Following redirects & downloading
By default curl does not follow a 3xx redirect — it prints the redirect response and
stops. Add -L to follow the chain to the final destination:
curl -L https://example.com/download/latest
To save the result instead of printing it, use -o to name the file yourself, or -O to
reuse the name from the URL:
curl -L -o gophertrunk.tar.gz https://example.com/releases/gt.tar.gz
curl -L -O https://example.com/releases/gophertrunk.tar.gz
When downloading is all you want, wget is the download-focused alternative: it saves to a file by default, resumes interrupted transfers, and can fetch recursively. curl is the request inspector; wget is the file grabber.
wget https://example.com/releases/gophertrunk.tar.gz
Why it’s a superpower
Because a curl command is just text, every request is reproducible and scriptable. You
can paste it into a bug report, drop it in a shell script, or run it in a loop to watch a
service. When an API returns the wrong thing, one curl line with -v shows you the exact
status, headers, and body — no browser guesswork. It is the natural next step after the
basic connectivity checks: once you know the
host is reachable, curl tells you what it is actually saying.
Quick check: which curl flag shows only the response headers?
Recap
- curl sends an HTTP request from the shell and prints the response;
-squiets the progress meter. - Read the response with
-I(headers only),-i(headers + body), or-v(the whole exchange, including TLS). - Shape a request with
-X(method),-d(body), and-H(headers) — send JSON with aContent-Typeheader, and keep secrets out of the URL. -Lfollows redirects;-oand-Osave to a file; wget is the download-focused alternative.- Because it is plain text, curl makes requests reproducible and scriptable — ideal for diagnosing an API or a service.
Next up: SSH tunnels & transfers