// DevOps

curl for beginners: your first step into the world of HTTP requests

Published on 2026-09-22

curl — a command-line utility for transferring data via URLs. It sends a request to a server and shows the response: an HTML page, JSON from an API, headers, or a file. The name stands for Client URL. Besides HTTP and HTTPS, curl works with FTP, SFTP, SMTP, IMAP, and other protocols.

curl is available on almost every Linux and macOS system, and is included in Windows 10 and 11. People use it to:

  • test APIs and web services without a browser;
  • download files in scripts;
  • check site availability, redirects, and certificates;
  • find where time is lost when loading a page;
  • send test emails via SMTP.

First request

Without options curl performs a GET request and prints the response body to the terminal:

bash
curl https://example.com

Main flags

Descriptions — from the official curl manual.

FlagWhat it does
-s, --silentdo not show the progress meter and error messages
-S, --show-errortogether with -s: still show an error message if the request failed
-L, --locationfollow redirects (3xx)
-I, --headfetch only response headers (for HTTP — HEAD request)
-i, --includeprint response headers along with the body
-v, --verboseverbose output: connection, TLS, request headers (>) and response headers (<)
-o filesave the response to the specified file
-Osave the file with the name from the URL
-X methodset the request method: POST, PUT, DELETE, etc.
-H "Name: value"add a header
-d datasend data with POST, by default as application/x-www-form-urlencoded
--data-urlencodesame as -d, but URL-encodes the value
--json datasend JSON: sets Content-Type and Accept: application/json
-u user:passusername and password for basic authentication
-f, --failon 400+ response, exit with code 22 and do not output the body
--retry Nretry the request on transient errors
-w formatprint informational data after the request: response code, timing stages
-m, --max-timelimit the total operation time in seconds
--connect-timeoutlimit only the time to establish the connection
-x addresssend the request through a proxy
-k, --insecuredo not verify the server certificate

The -k flag disables TLS certificate verification, and the connection is no longer protected against tampering. It is acceptable only for diagnostics on your own testbed; it has no place in scripts and production settings.

The combination -sS is convenient in scripts: progress does not clutter the output, but errors are visible. For downloading in a script people usually write curl -fsSL: no progress, error messages shown, follow redirects, and a non-zero exit code if the server responded with an error.

Headers and redirects

View only response headers:

bash
curl -I https://example.com

Check where a redirect chain leads and see the headers of each response:

bash
curl -sIL http://example.com

Verbose output with TLS connection details is the first thing to do if a request behaves strangely:

bash
curl -v https://example.com -o /dev/null

API requests

GET request with an Authorization header:

bash
curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/v1/items

POST with form data:

bash
curl -d "name=mike&age=30" https://api.example.com/register

If -d is specified, the POST method is chosen automatically; you don’t need to add -X POST.

POST with JSON:

bash
curl --json '{"name": "mike", "age": 30}' https://api.example.com/users

In older versions of curl that don’t have --json yet, the same is written like this:

bash
curl -H "Content-Type: application/json" -d '{"name": "mike", "age": 30}' https://api.example.com/users

PUT and DELETE:

bash
curl -X PUT --json '{"age": 31}' https://api.example.com/users/42
curl -X DELETE https://api.example.com/users/42

Basic authentication:

bash
curl -u admin:password https://example.com/admin/

If you only specify a username (-u admin), curl will ask for a password interactively, and it won’t remain in the command history.

Downloading and uploading files

bash
# save with the name from the URL
curl -O https://example.com/file.zip

# save under your own name
curl -o backup.zip https://example.com/file.zip

# send a file via a form (multipart/form-data)
curl -F "file=@report.pdf" https://example.com/upload

# upload a file via PUT
curl -T report.pdf https://example.com/files/report.pdf

How long a request takes

The -w flag prints informational variables after the request. This way you can understand at which stage time is being lost:

bash
curl -o /dev/null -s -w "DNS: %{time_namelookup}\nTCP: %{time_connect}\nTLS: %{time_appconnect}\nFirst byte: %{time_starttransfer}\nTotal: %{time_total}\nCode: %{http_code}\n" https://example.com

All values are in seconds from the start of the request. If DNS time is high, the problem is with the resolver; if time to first byte is high on a fast connection, the application itself is responding slowly. More on network troubleshooting — see the article “Network troubleshooting: diagnostic utilities”.

Response code alone, for example for monitoring in a script:

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

Timeouts, retries, and proxies

bash
# don't wait longer than 5 seconds for the connection, and longer than 20 seconds for the whole request
curl --connect-timeout 5 -m 20 https://example.com

# retry up to three times on transient errors
curl --retry 3 https://example.com

# request via an HTTP proxy or SOCKS5
curl -x http://proxy.example.com:3128 https://example.com
curl -x socks5h://127.0.0.1:1080 https://example.com

The scheme socks5h:// means that the proxy resolves the server name, not your computer.

Mail protocols

Sending an email via SMTP

bash
curl --url "smtp://smtp.example.com:587" \
  --ssl-reqd \
  --mail-from "sender@example.com" \
  --mail-rcpt "recipient@example.com" \
  --upload-file email.txt \
  --user "username:password"
  • --ssl-reqd — require encryption (STARTTLS);
  • --mail-from and --mail-rcpt — sender and recipient;
  • --upload-file — a file with the email: headers From, To, Subject, a blank line, and the body.

Listing folders via IMAP

bash
curl --url "imaps://imap.example.com" \
  --user "username:password" \
  -X 'LIST "" "*"'

Common mistakes

  • Forgotten -L. The server responds with a redirect, and curl shows an empty response or a “Moved” page.
  • -k in production scripts. The script stops noticing certificate tampering. It’s better to fix the certificate chain on the server or specify your own root certificate via --cacert.
  • Passwords and tokens on the command line. They stay in the shell history and are visible in the process list. It’s better to pass tokens via environment variables or a file (-H @headers.txt).
  • Missing -f in scripts. Without it, a 404 or 500 response is considered a successful request, and the script will continue working with a “file” that is actually an error page.

curl nicely complements browser developer tools: its command can be easily saved, repeated, and inserted into a script or a CI job.

How to use curl to find the cause of a problem — send a request to a specific server bypassing DNS, trace the redirect chain, break down where time is lost — is described in the article “Debugging HTTP with curl”. Certificate and TLS checks are covered in “TLS debugging: curl and openssl s_client”.

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply