>_cmd.script

curl

Transfer data to/from a URL over many protocols

Networking

By CMD Script Team · 4 min read · Last updated

SYNTAX
curl [OPTIONS] URL...

Options

Command options and flags
FlagDescription
-OSave output to a local file using the remote file's name
-LFollow HTTP redirects (3xx responses)
-XSet the HTTP request method, e.g. -X POST
-HAdd a custom request header, e.g. -H 'Content-Type: application/json'
-dSend data in the request body (implies POST unless -X overrides it)
-IFetch headers only, using an HTTP HEAD request
-sSilent mode, suppress the progress meter and error messages
-vVerbose mode, show the full request/response exchange

Distribution compatibility

  • Ubuntu
  • Debian
  • Fedora
  • Arch
  • macOS

What it does

curl (Client URL) transfers data to or from a server using any of a huge number of supported protocols — HTTP, HTTPS, FTP, SFTP, and more — from the command line. It's the standard tool for scripting HTTP requests: testing APIs, downloading files, checking response headers, or debugging web services, and it exposes fine-grained control over methods, headers, and request bodies that makes it a staple of both development and operations work.

Beginner examples

  • curl https://example.com — fetch a URL and print the response body to stdout
  • curl -O https://example.com/file.zip — download a file, saving it under its remote name
  • curl -I https://example.com — fetch only the response headers
  • curl -L https://example.com — follow redirects to reach the final URL
curl -o page.html https://example.com

Advanced examples

  • Send a POST request with a JSON body: curl -X POST -H "Content-Type: application/json" -d '{"name":"alice"}' https://api.example.com/users
  • Add an authorization header for an API call: curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me
  • Submit form data: curl -X POST -d "username=alice&password=secret" https://example.com/login
  • Save a download while following redirects: curl -L -O https://example.com/latest-release
  • Time a request's phases for performance debugging: curl -w "%{time_total}\n" -o /dev/null -s https://example.com
curl -sSL -X GET -H "Accept: application/json" https://api.example.com/status

Common mistakes

  • Forgetting -L and being confused why a redirected URL "didn't work" — curl prints the redirect response instead of following it unless told to.
  • Using -d without realizing it implicitly switches the request to POST, which can be surprising when you only meant to attach data to a GET.
  • Not quoting JSON bodies properly in the shell, leading to broken quotes/escaping — wrapping the JSON in single quotes (and using \" inside if needed) avoids most of this.
  • Assuming curl -O respects a custom filename — it always uses the remote URL's basename; use -o filename when you need control over the local name.

Tips

  • Add -s in scripts to suppress the progress meter, and pair it with -S (-sS) to still show errors even in silent mode.
  • Use -v when a request behaves unexpectedly — it prints the full request and response headers, revealing redirects, auth failures, or unexpected content types.
  • curl -w with a format string can extract specific metrics (status code, total time, size) for lightweight scripted health checks.

Best practices

  • Always check the HTTP status code in scripts (curl -o /dev/null -s -w "%{http_code}\n" URL) rather than assuming a request succeeded just because curl didn't error.
  • Prefer -H "Authorization: Bearer $TOKEN" over embedding secrets in URLs, which can leak into logs and shell history.
  • Use --fail (-f) in scripts so curl returns a non-zero exit code on HTTP error responses (4xx/5xx) instead of silently succeeding with an error page as the body.

Try it yourself

A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.

Real-world use cases

  • Testing and debugging REST APIs during development, sending custom methods, headers, and bodies without needing a full HTTP client library.
  • Downloading release artifacts, container base images, or installers inside Dockerfiles and CI pipelines.
  • Health-checking a service endpoint in a monitoring script by checking the returned HTTP status code.

Common interview questions

  • How do you send a POST request with a JSON payload using curl? curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' URL — the header declares the body format and -d supplies the payload.
  • How would you make curl fail (non-zero exit code) on an HTTP error response? Add -f/--fail, which makes curl return an error instead of printing the server's error page as if it succeeded.
  • What's the difference between -o and -O? -o filename saves output under a name you choose; -O saves it using the remote URL's own filename.

Frequently Asked Questions

What's the difference between curl -O and curl -o?

curl -O saves the downloaded file using the same name as in the URL; curl -o filename lets you choose the local filename explicitly.

How do I send a JSON POST request with curl?

curl -X POST -H 'Content-Type: application/json' -d '{"name":"alice"}' https://api.example.com/users — the -H sets the content type and -d supplies the JSON body.

How do I see just the HTTP response headers without the body?

curl -I https://example.com sends a HEAD request and prints only the response headers, useful for checking status codes, redirects, or content type quickly.

Why didn't curl follow a redirect?

By default curl does not follow 3xx redirects; add -L to make it follow them automatically to the final destination URL.

Cheat sheet

Download a quick-reference cheat sheet for curl.