Use curl URL to fetch a webpage’s HTTP response. The response body is written to your terminal unless you redirect it with -o or -O. curl retrieves what the server sends; it does not execute JavaScript or render a page like a browser. For a predictable download, run:
curl --output page.html https://example.com/
This guide shows how to save page bodies, inspect headers, follow redirects, preserve cookies, add request headers, diagnose failures, and decide when a browser-based screenshot service is more appropriate.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
Dan Gookin's Guide to Curl Programming | $11.95 | Buy on Amazon |
| 2 |
|
Curly Girl: The Handbook | $8.19 | Buy on Amazon |
| 3 |
|
The C Programming Language | $40.21 | Buy on Amazon |
| 4 |
|
Curl by Example | $0.99 | Buy on Amazon |
| 5 |
|
A Practical Guide to Curl (Programming Series) | $24.99 | Buy on Amazon |
Fetch a webpage to the terminal
A bare GET request prints the returned body to standard output:
curl https://example.com/
For HTML, that usually means markup appears in your terminal. curl does not parse the HTML, load client-side JavaScript, click controls, or display the final visual layout. The representation can therefore differ substantially from what a browser shows.
#1 Best Overall
Save the response body to a file
Choose an explicit filename with -o
Use lowercase -o (also written --output) when scripts need a stable local path:
curl --output page.html https://example.com/
curl writes the response body to page.html. Existing files can be overwritten, so select the destination deliberately.
Use the remote filename with -O
Uppercase -O (or --remote-name) derives the filename from the URL:
curl --remote-name https://example.com/archive.zip
This is convenient for downloads whose URL ends in a meaningful filename, but it is less predictable for automation and often produces an unhelpful name for dynamic URLs.
Free tools Windows power users keep installed
One-click scans. No signup required.
Save a page and retain a useful exit status
For unattended jobs, add a timeout appropriate to the task and handle curl’s exit code in your shell. There is no universal timeout: a small API response and a large document need different limits.
curl --connect-timeout 10 --max-time 90 --output page.html https://example.com/
--connect-timeout bounds connection setup; --max-time bounds the complete operation. Check the installed manual for behavior on your curl version.
Rank #2
Capture response headers and body
Show headers together with the body using -i
curl --include https://example.com/
--include (short form -i) prints response headers first, followed by the body. This is useful for a quick inspection, but it mixes metadata and content in one stream.
Write headers to a separate file with -D
curl --dump-header headers.txt --output page.html https://example.com/
Now page.html contains only the body and headers.txt contains the received headers. This separation is safer for parsers and makes it easy to inspect status, content type, caching, cookies, and redirects.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Request headers only with -I
curl --head https://example.com/
--head (short form -I) sends a HEAD request and asks for headers without a response body. It is useful for metadata checks, but some servers reject or mishandle HEAD even though GET works. If that happens, use GET with --dump-header and discard or save the body.
Follow redirects explicitly
curl stops at the first HTTP response by default. Follow Location responses with -L (or --location):
curl --location --dump-header headers.txt --output page.html https://example.com/
When redirects occur, the header file can contain multiple response blocks. Review the destination before sending credentials or state. curl does not automatically pass authorization and cookie headers to a different origin; avoid options that relax this protection unless you have verified every redirect target.
Add request headers and a user agent only when needed
Most public pages need neither custom headers nor a special user agent. If an endpoint requires them:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
curl --header 'Accept: text/html' https://example.com/
curl --user-agent 'ExampleResearchBot/1.0' https://example.com/
These alter what you send, not what curl can render. A user-agent string does not turn curl into a browser, and a server can still return a JavaScript shell or a bot challenge.
Preserve cookies across requests
Use a cookie jar instead of manually copying Set-Cookie text:
curl --cookie-jar cookies.txt --output page.html https://example.com/
To send the stored cookies on a later request and update the same jar:
curl --cookie cookies.txt --cookie-jar cookies.txt --output next.html https://example.com/next
Cookie jars can contain session identifiers. Restrict their file permissions, do not commit them to source control, and remove them when the session is no longer needed.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesGET, HEAD, redirects, and cookies: choose by outcome
| Goal | Command pattern | Result |
|---|---|---|
| See the body in a terminal | curl URL |
Body to standard output; no redirect following |
| Save one body file | curl -o page.html URL |
Body in the named file |
| Save using URL filename | curl -O URL |
Body in a derived filename |
| Inspect headers and body together | curl -i URL |
Headers followed by body |
| Save headers separately | curl -D headers.txt -o page.html URL |
Separate metadata and body files |
| Ask for metadata only | curl -I URL |
HEAD response without a body; may be rejected |
| Follow redirects | curl -L URL |
Requests redirect destinations |
| Reuse session state | curl -b cookies.txt -c cookies.txt URL |
Read and update a cookie jar |
What curl cannot capture
curl downloads an HTTP representation, not a rendered browser screenshot. Pages that build content with JavaScript, require a consent interaction, lazy-load images, or depend on browser APIs may produce incomplete HTML. A successful HTTP transfer therefore does not guarantee that the page is visually complete.
If the requirement is a pixel-accurate, full-page image or PDF, use a browser automation workflow or a screenshot API rather than trying to convert curl output into a screenshot.
Rank #4
Or skip the browser setup
ScreenshotNeo provides a one-request website screenshot API and MCP server. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
Use the API when you need a rendered PNG, JPEG, WebP, or PDF instead of raw HTML:
Recommended Free Tools
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for output and option details. The service also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every plan includes features such as full-page capture with lazy images loaded, CSS-selector element capture, device presets, custom CSS and JavaScript, waits, request blocking, cookies and headers, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and a usage API.
There is a free allowance of 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free. Create a free ScreenshotNeo account.
Equivalent calls from Python and Node.js
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot common failures
“Could not resolve host”
DNS resolution failed. Check the spelling, network connectivity, VPN, proxy, and DNS configuration. Try another known hostname to distinguish a local problem from a domain problem.
Connection timeout or reset
The server or network did not complete the connection. Set task-appropriate --connect-timeout and --max-time values, retry transient failures carefully, and verify whether a proxy or firewall is interfering.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →HTTP 3xx but the file is not the final page
Use --location. Inspect the header file to confirm each destination, especially when credentials or cookies are present.
Best Value
HTTP 401 or 403
The endpoint requires authentication or denies the client. Confirm the documented authentication method, use HTTPS, and keep secrets out of shell history and shared logs. Do not assume changing the user agent bypasses access controls.
HEAD fails while GET succeeds
Some servers do not implement HEAD correctly. Replace --head with a GET that uses --dump-header; save the body or redirect it as appropriate.
The HTML is empty, incomplete, or a challenge page
Inspect status, content type, and body. The site may require JavaScript, cookies, a browser interaction, or human verification. curl cannot solve a browser-only flow; use an authorized browser automation or screenshot service.
An option is unknown
Capabilities vary with the curl version and build. Check:
curl --version
curl --help all
Consult the installed manual for exact option semantics, supported protocols, and platform-specific behavior.
Security and automation checklist
- Prefer HTTPS for credentials and session traffic.
- Never hard-code passwords, API keys, or bearer tokens in published commands.
- Protect cookie jars; they may grant access to an account.
- Review redirect destinations before allowing stateful requests.
- Verbose and trace output can expose headers, cookies, URLs, and other private data; redact logs before sharing.
- Use
--failonly with a clear understanding of how your installed version treats HTTP error responses, and distinguish HTTP errors from transport failures in scripts. - Validate the downloaded content type and size before processing untrusted responses.
Frequently Asked Questions
Does curl execute a webpage’s JavaScript?
No. curl performs HTTP transfers and returns server responses; it does not provide a browser’s JavaScript runtime or visual rendering engine.
Why does curl show headers from more than one response?
When redirects are followed, each response can contribute a header block. Save headers with --dump-header and inspect the blocks in order.
Is -o different from shell output redirection?
Yes. -o is curl’s output-file option and works consistently with curl’s transfer handling; shell redirection also captures diagnostics unless you redirect streams separately.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

