Date-stamped: March 2026. curl is one of the most stable tools in the terminal ecosystem, but new flags and protocols do get added. When in doubt, run curl --help all or check the official manual.
Cross-platform: curl is pre-installed on macOS and most Linux distributions. On Windows, it ships with Windows 10+ and is available in Git Bash. The examples here work across all three.
Basic Usage
The simplest curl command fetches a URL and prints the response to your terminal. No file saved, no browser opened — just raw output.
Fetch and Print
This is where I started. One command, one URL, and the server's response lands right in the terminal.
curl https://example.com The entire HTML of the page prints to stdout. It looks messy — that is what HTML looks like before a browser renders it.
Follow Redirects
The -L Flag
Many URLs redirect — http to https, short links to full URLs. Without -L, curl stops at the redirect and you get nothing useful. I learned this the hard way when every response came back empty.
curl -L https://example.com Prof. Teeters told me: "If curl gives you an empty response, the first thing to try is -L."
Headers Only
The -I Flag
Sometimes I do not need the body — I just want to know the content type, status code, or caching headers. -I sends a HEAD request and shows only the response headers.
curl -I https://example.com # Example output:
# HTTP/2 200
# content-type: text/html; charset=UTF-8
# content-length: 1256
# cache-control: max-age=604800 Save to File
The -o Flag
Instead of flooding the terminal, save the response to a file. I use this when downloading assets or saving API responses for later inspection.
curl -o output.html https://example.com Use -O (uppercase) to save with the remote filename instead of choosing your own.
Custom Headers
The -H Flag
This is where curl got real for me in Station 6. APIs need authentication tokens, content types, and other headers. -H lets you add any header you want.
# Send an authorization header
curl -H "Authorization: Bearer TOKEN" https://api.github.com/user
# Send multiple headers
curl -H "Authorization: Bearer TOKEN" \
-H "Accept: application/json" \
https://api.example.com/data Replace TOKEN with your actual token. Never commit tokens to git — I learned that from Grace, who was very clear about it.
POST Data
The -X and -d Flags
GET requests fetch data. POST requests send data. When I needed to create resources through an API, this was the pattern.
curl -X POST \
-H "Content-Type: application/json" \
-d '{"key":"value"}' \
https://api.example.com/items -X POST sets the HTTP method. -d sends the data payload. -H tells the server what format the data is in. All three work together.
What curl Does NOT Do
This tripped me up early on. I expected curl to behave like a browser. It does not. Understanding its limits made me better at using it.
No JavaScript execution
curl fetches the HTML the server sends. If the page builds its content with JavaScript after loading, curl will not see that content. You get the raw HTML — nothing more.
No cookies by default
Browsers store and send cookies automatically. curl does not — unless you tell it to with -b (send cookies) and -c (save cookies).
# Save cookies to a file
curl -c cookies.txt https://example.com/login
# Send cookies from a file
curl -b cookies.txt https://example.com/dashboard No rendering
What you see is raw HTTP response text. No layout, no styling, no images. That is the point — you see what the server actually sends, not what the browser interprets.
Common Flags Reference
The flags I use most often, all in one place.
Follow redirects
Follow HTTP redirects (301, 302, etc.) until reaching the final destination.
Output to file
Save the response body to a named file instead of printing to terminal.
Headers only
Send a HEAD request and display only the response headers.
Custom header
Add a custom header to the request. Use multiple -H flags for multiple headers.
HTTP method
Set the request method: GET, POST, PUT, DELETE, PATCH.
Send data
Send data in the request body. Implies POST unless -X specifies otherwise.
Silent mode
Hide the progress meter and error messages. Useful in scripts or when piping output to another command.
Verbose
Show the full request and response conversation — headers sent, headers received, TLS handshake. When something is not working, -v is the first flag I add.