The curl Command

Run a Speed Test

curl (Client URL) makes HTTP requests from the command line — letting you fetch pages, test APIs, inspect headers, debug redirects, and verify TLS certificates without opening a browser.

What curl Does

curl is a command-line tool for transferring data using URLs. It supports HTTP, HTTPS, FTP, FTPS, SFTP, and a dozen other protocols, but its primary use is making HTTP and HTTPS requests. curl sends a request, prints the response body to standard output, and exits — making it trivially composable with other shell tools.

The use cases are broad: fetching a web page to verify it loads, testing a REST API endpoint, downloading a file, checking which HTTP headers a server returns, following a redirect chain to see where a URL ultimately lands, verifying a TLS certificate, or timing how long a server takes to respond. curl does all of these from a single command and is available on Linux, macOS, and Windows without installing anything extra.

Basic GET Requests

The simplest form prints the response body to the terminal:

curl https://example.com

Add -L to follow redirects (many URLs redirect from HTTP to HTTPS, or from a bare domain to www):

curl -L https://example.com

To see only the HTTP response headers without the body, use -I (which sends a HEAD request):

curl -I https://example.com

To see both request and response headers plus the body, use -v (verbose). This is the most useful debugging mode — it shows the TLS handshake, the exact headers sent and received, and the response body:

curl -v https://example.com

Key Flags Reference

FlagPurpose
-LFollow redirects (up to 30 by default)
-IHEAD request — response headers only, no body
-vVerbose — show request headers, response headers, TLS handshake
-sSilent — suppress progress meter and error messages
-o FILESave response body to FILE
-OSave response body using the remote filename from the URL
-X METHODSet HTTP method (GET, POST, PUT, DELETE, PATCH)
-d DATARequest body for POST/PUT (implies POST if no -X given)
-H "Header: value"Add a request header
-u user:passHTTP Basic Authentication
-kSkip TLS certificate verification (insecure — for testing only)
--max-time NAbort if the entire transfer takes longer than N seconds
--connect-timeout NAbort if the connection cannot be established within N seconds
-w FORMATPrint custom output after transfer (e.g. HTTP status code, timing)

Making POST Requests and Testing APIs

For a form POST, use -d with key=value pairs:

curl -X POST -d "username=alice&password=secret" https://example.com/login

For a JSON API, set the Content-Type header and pass JSON as the body. Use single quotes around the JSON to avoid shell escaping issues:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_token_here" \
  -d '{"name":"Alice","role":"admin"}' \
  https://api.example.com/users

To read the request body from a file (useful for large payloads), prefix the filename with @:

curl -X POST -H "Content-Type: application/json" -d @payload.json https://api.example.com/endpoint

Pipe the output through jq to pretty-print JSON responses:

curl -s https://api.example.com/data | jq .

Checking HTTP Status Codes

The -w flag prints custom information after the transfer. The most useful variable is %{http_code}. Combine with -s -o /dev/null to discard the body and print only the status code — useful in scripts:

curl -s -o /dev/null -w "%{http_code}" https://example.com

Other useful -w variables: %{time_total} (total request time in seconds), %{time_connect} (time to TCP connect), %{time_starttransfer} (TTFB — time to first byte), %{size_download} (bytes downloaded), and %{url_effective} (final URL after redirects).

Inspecting TLS Certificates

curl's verbose mode shows the full TLS handshake including the server certificate chain. To check certificate expiry and subject details without parsing verbose output, combine with openssl:

curl -v https://example.com 2>&1 | grep -A 10 "Server certificate"

To test a server that has a self-signed or invalid certificate during development, add -k to skip verification. Never use -k in production scripts — it disables all TLS security.

Frequently Asked Questions

How do I make a POST request with curl?

Use -X POST -d "body": curl -X POST -d "key=value" https://example.com/api. For JSON, add the Content-Type header: curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.com/endpoint. To read the body from a file, use -d @filename.json.

How do I follow redirects with curl?

Add -L: curl -L https://example.com. Without -L, curl stops at the redirect and prints the 301/302 response. With -L, it follows up to 30 redirects. Add -v to see each redirect URL as it follows the chain.

How do I save a file with curl?

Use -o filename to specify the output file: curl -o page.html https://example.com. Or use -O (capital O) to save with the filename from the URL. Add --progress-bar to show a simple progress bar for large downloads instead of the default statistics display.

How do I test an API with curl?

Combine -X for the method, -H for headers, and -d for the body. For a bearer token API: curl -H "Authorization: Bearer token" https://api.example.com/resource. Add -s to suppress the progress meter and pipe to jq for readable JSON output.

What is the difference between curl and wget?

curl is optimized for making HTTP requests and inspecting responses — ideal for API testing, debugging, and scripting HTTP interactions. wget is optimized for downloading files and recursive website mirroring, with built-in support for resuming interrupted transfers. curl outputs to stdout by default; wget saves to files. For HTTP debugging, curl is more powerful. For downloading files in scripts, either works well.

Is curl available on Windows?

Yes. curl has been included as a built-in command in Windows 10 since the April 2018 update and works in both Command Prompt and PowerShell. It is the same binary as the Linux and macOS versions with identical flag support. On older Windows versions, download curl from curl.se or use Windows Subsystem for Linux.

Related Guides

More From This Section