ScreenshotNeo

BlogHow-to

How to Use the curl Command to Make HTTP Requests

Learn to send HTTP requests with curl, inspect responses, submit data, handle redirects, and troubleshoot common errors with practical examples.

By the ScreenshotNeo team4 October 20268 min read

curl is a command-line tool for transferring data to and from a server. To make a basic HTTP GET request, run curl https://example.com/. The response body prints to your terminal. To do more, choose the HTTP method, headers, and request body that the endpoint expects, then inspect the response status and headers.

curl transfers HTTP data; it does not render HTML like a browser or interpret an API response as application data. The server’s API contract determines which methods, fields, formats, authentication, and permissions are valid. [curl HTTP scripting guide]

1. Make a basic GET request

curl https://example.com/

A request to a URL uses GET by default. curl writes the response body to standard output, so HTML or JSON may appear directly in the terminal. Save the response instead with -o:

curl -o response.html https://example.com/

To save it using the remote filename, use -O:

curl -O https://example.com/files/report.csv

Use -L or --location when you want curl to follow redirects. Without it, curl shows the redirect response rather than automatically requesting the destination.

curl -L https://example.com/old-path

2. Inspect status and response headers

There are several ways to see headers, and they do different things:

Option What it does Typical use
-I or --head Sends a HEAD request and prints response headers without the body. Check metadata when the server supports HEAD.
-i or --include Includes response headers in the output along with the body. Inspect headers and content in one response.
-D file or --dump-header file Writes response headers to a file. Save headers for later inspection.
-v or --verbose Shows request and response protocol details. Diagnose connection, TLS, header, or redirect behavior.
# Request headers only (this sends HEAD, which some servers reject)
curl -I https://example.com/

# Show response headers together with the response body
curl -i https://example.com/

# Save response headers separately
curl -D headers.txt -o response.html https://example.com/

# Show request and response details
curl -v https://example.com/

Remember: -I changes the request to HEAD, while -i leaves the request as GET and adds returned headers to the output. A server may reject HEAD even when a GET request to the same URL succeeds. [curl man page, HTTP scripting guide]

3. Add request headers

Use -H or --header to add or replace a request header. For example, an API may use the Accept header to select a response format:

curl -H 'Accept: application/json' https://api.example.com/items

For a bearer token, pass an authorization header. Replace the placeholder with a credential the endpoint issued to you:

curl -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Accept: application/json' \
  https://api.example.com/items

Quote header values containing spaces or shell-special characters. curl also lets an empty header value suppress a header it would otherwise send; avoid copying an empty override unless that is intentional. [curl man page]

4. Send POST data

Form-encoded data

-d or --data sends a POST body. By default, curl treats this as form data with the content type application/x-www-form-urlencoded:

curl -d 'name=Sam&role=editor' https://api.example.com/items

URL-encode values that contain characters with special meaning in a form or URL. For complicated values, use a tool or language library that handles form encoding rather than assembling an unescaped string by hand.

JSON data

For a JSON endpoint, send a JSON body and set the matching content type:

curl -X POST https://api.example.com/items \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"name":"Sam"}'

The endpoint decides whether the format and fields are accepted. A syntactically valid JSON body can still fail if the API requires different fields, authentication, or permissions.

Preserve the supplied body bytes

Use --data-binary when you need curl to preserve the body exactly, including newlines. Set a content type appropriate for the endpoint; the default data content type may not match what the server expects.

curl --data-binary @payload.json \
  -H 'Content-Type: application/json' \
  https://api.example.com/import

5. Choose the right HTTP method behavior

Prefer curl options that match the transfer you want to perform. -d sends data as a POST by default; -I makes a HEAD request; and -T or --upload-file uploads a file, typically using PUT for HTTP:

# HEAD request
curl -I https://example.com/

# POST a body
curl -d 'name=Sam' https://api.example.com/items

# Upload a file (the server must accept the upload)
curl -T ./report.csv https://api.example.com/uploads/report.csv

-X or --request changes the method string curl sends. It does not configure the transfer behavior associated with that method. For example, -X HEAD alone does not make a proper HEAD transfer; use -I. A custom -X method can also remain in effect across redirects. [HTTP scripting guide, curl man page]

6. Runnable examples in Python and Node.js

These examples use the standard HTTP GET pattern. Replace the URL with an endpoint you are authorized to access.

Python

from urllib.request import urlopen

url = "https://example.com/"
with urlopen(url, timeout=30) as response:
    print("Status:", response.status)
    print("Content-Type:", response.headers.get("Content-Type"))
    body = response.read()

with open("response.html", "wb") as output:
    output.write(body)

Node.js

const response = await fetch('https://example.com/');
console.log('Status:', response.status);
console.log('Content-Type:', response.headers.get('content-type'));

const body = await response.text();
await import('node:fs/promises').then(({ writeFile }) =>
  writeFile('response.html', body)
);

Python’s standard library and Node.js’s built-in fetch are alternatives when you need to integrate HTTP requests into a program. Their APIs and error handling differ from curl; use the documentation for your runtime when adapting the examples.

7. Troubleshoot common curl problems

Symptom Likely cause What to try
You see HTML or JSON printed in the terminal. curl writes the response body to standard output by default. Use -o response.html to save it, or pipe it into a tool that handles the content.
-I fails but a regular request works. The server does not support or allow HEAD. Try GET with -i to inspect headers alongside the body.
The server returns an error or unexpected response. The method, content type, body fields, authentication, or permissions may not match the API contract. Check the response status and headers with -i; compare the request with the endpoint’s documentation.
The server responds with a redirect instead of the content. The endpoint points to another URL and curl is not following redirects. Use -L after checking that the destination is expected.
A POST body arrives with unexpected characters or formatting. Form data was not encoded as intended, or the server expects another content type. Use the API’s expected format, set Content-Type, and consider --data-binary when exact bytes matter.
An upload is rejected. The server may not accept uploads at that URL or with that method, or it may require authentication or a specific content type. Check the upload endpoint’s contract and permissions; -T does not make a server accept an upload.
Verbose output is hard to share safely. Diagnostics can include request details and sensitive values. Protect the log and redact tokens, cookies, credentials, and personal data before sharing.

For deeper diagnostics, write an ASCII trace to a file:

curl --trace-ascii trace.txt https://example.com/

Verbose and trace output can contain private request or response data. Keep it out of public issue reports unless sensitive values have been removed. [curl known risks]

8. Handle redirects and credentials carefully

Before forwarding a request across a redirect, confirm that the destination is trusted. Custom methods and sensitive headers require particular care: a custom -X method can persist across redirects, and configuration choices can expose credentials to another server. Do not use --location-trusted casually. Inspect the redirect destination, and avoid sending tokens or cookies where they are not intended. [curl known risks, curl man page]

9. Performance, reliability, and cost

  • Performance: Keep the request focused on the data you need. Saving a large response to a file avoids flooding the terminal, but it does not reduce the bytes transferred. Use the endpoint’s supported options and response formats to limit work where possible.
  • Reliability: A successful transfer does not necessarily mean the server accepted the intended operation. Inspect the HTTP status and response body. Use a timeout appropriate to the endpoint when building scripts, and handle failures explicitly in automation.
  • Retries: Retrying a request can repeat a side effect, especially for POST or other operations that create or change data. Follow the API’s guidance on idempotency and retry behavior rather than blindly repeating an operation.
  • Cost: curl itself is a command-line transfer tool; any usage charges depend on the server or API you call. Review the endpoint provider’s pricing and rate limits.
  • Version differences: Options can vary by installed curl version and build. Check curl --help or the installed man page for the options available in your environment. The official curl documentation includes the tutorial and detailed references.

10. Or skip the browser setup

curl is useful for HTTP requests, but it does not render a webpage as a browser screenshot. For a screenshot, ScreenshotNeo provides a one-call website screenshot API. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000 shots, and every feature is on every plan.

Sign up for 1,000 free screenshots a month, with no card required.

Frequently asked questions

Is curl available on my system?

Check by running curl --version. If the command is missing, install curl using the package manager or installation instructions for your operating system.

Does curl execute JavaScript on a webpage?

No. curl transfers the HTTP response; it does not run page JavaScript or render the page like a browser.

Where can I learn every curl option?

Use the installed curl --help or man page for options available in your build, and consult curl’s official documentation for the tutorial, man page, and HTTP scripting guide.