- What Is curl?
curl (short for Client URL) is a powerful command-line tool to:
- send HTTP(S) requests,
- download or upload files,
- interact with APIs,
- debug network problems.
- It supports many protocols:
- HTTP, HTTPS
- FTP, FTPS, SFTP
- SCP, SMTP, POP3, IMAP, and more (depending on build)
- Typical use cases:
- Checking a website response
- Calling a REST API from the terminal
- Downloading files
- Sending form data or JSON payloads
- Testing authentication and headers
curl is installed by default on many Linux/macOS systems; Windows has official builds too.
- Basic Syntax
curl <options> <URL>
# Fetch a web page and print to terminal (stdout)
curl https://example.com
# Fetch over HTTP
curl http://example.com
- If you provide no options,
curl:
- sends an HTTP
GET request,
- prints the response body to the terminal.
- Saving Output to a File
- By default, the response body is printed to the screen.
- To save it to a file, you have two common options:
# 1) Shell redirection
curl https://example.com > page.html
# 2) Let curl decide file name from URL with -O (uppercase O)
curl -O https://example.com/file.zip
# 3) Save to a chosen file name with -o (lowercase o)
curl -o mypage.html https://example.com
-O: use the file name from the URL.
-o: explicitly specify the file name.
- Seeing Response Headers
- Sometimes you want to see HTTP headers (status code, content type, etc.).
- Use
-i (include headers in output):
curl -i https://example.com
- This prints:
- status line (e.g.
HTTP/1.1 200 OK)
- response headers
- blank line
- response body
- Use
-I (uppercase i) to fetch only the headers via an HTTP HEAD request:
curl -I https://example.com
- Following Redirects
- Many sites redirect (e.g. from
http to https).
- By default,
curl does not follow redirects.
- Use
-L to follow them:
curl -L http://example.com
- Now
curl will automatically follow the Location headers until it reaches the final URL.
- Adding Custom Headers
- APIs often require custom HTTP headers (e.g. auth tokens, content type).
- Use
-H (or --header) to add a header:
curl -H "X-My-Header: hello" https://example.com
# Multiple headers:
curl \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json" \
https://api.example.com/data
- Sending Query Parameters
- Query parameters are simply part of the URL:
curl "https://example.com/search?q=haskell&page=2"
- Be sure to quote the URL if it contains
& so the shell does not interpret it.
- HTTP Methods: GET, POST, PUT, DELETE, ...
- By default,
curl sends a GET request.
- Use
-X (or --request) to specify a method explicitly:
# Explicit GET
curl -X GET https://example.com
# DELETE
curl -X DELETE https://api.example.com/items/123
- For POST/PUT, you usually combine with
-d (send data).
- Sending Form Data (
application/x-www-form-urlencoded)
- Classic HTML forms send data encoded like
key=value&key2=value2.
- Use
-d (or --data) to send such data:
curl -X POST https://example.com/login \
-d "username=alice&password=secret"
- When you use
-d without -X, curl automatically uses POST and sets an appropriate content type.
- To send multiple fields:
curl https://example.com/form \
-d "field1=value1" \
-d "field2=value2"
- Sending JSON Data
- Modern APIs typically use JSON.
- When sending JSON:
- set the
Content-Type header,
- provide JSON payload via
-d.
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "age": 30}'
- If your shell uses quotes differently, be careful to escape them properly.
- Uploading Files
- Use
-F (form) to upload files with multipart/form-data (like HTML forms):
curl -X POST https://example.com/upload \
-F "file=@/path/to/local/file.txt"
- The
@ prefix tells curl to read the contents from a file.
- You can upload multiple fields/files:
curl https://example.com/upload \
-F "description=My file" \
-F "file=@/path/to/file.txt"
- Authentication
curl -u "username:password" https://api.example.com/secure
-u adds the appropriate Authorization: Basic ... header.
- Bearer Token (common for APIs):
curl https://api.example.com/data \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
- HTTPS and Certificates
- When using
https://, curl verifies the server’s TLS certificate.
- For debugging self-signed or local dev setups, you can (temporarily) skip verification:
curl -k https://self-signed.example.local
- Warning:
-k (or --insecure) disables certificate verification and is not recommended for production.
- Better: point
curl to a custom CA bundle with --cacert.
- Verbose and Debugging Output
- Use
-v (--verbose) to debug requests:
curl -v https://example.com
- This prints:
- request line and headers,
- response headers,
- TLS handshake info (for HTTPS).
- Use
--trace and --trace-ascii for even more low-level details.
- Setting User-Agent and Other Common Options
- Some servers behave differently based on the User-Agent header.
- Set it with
-A (or --user-agent):
curl -A "MyTestClient/1.0" https://example.com
- Other useful flags:
--compressed – ask server for compressed response (gzip, etc.)
--max-time <seconds> – limit total time of request
--connect-timeout <seconds> – limit connection setup time
- Rate Limiting and Repeated Requests
- For simple repeated calls with pauses, combine
curl with shell tools:
# Call an endpoint every 5 seconds (Ctrl-C to stop)
while true; do
curl -s https://example.com/health
echo
sleep 5
done
-s (silent) hides progress meter and errors (show only output), useful when scripting.
- Getting Help and Manual
- To see a quick summary of options:
curl --help
- For the full manual (very detailed):
man curl # on Unix-like systems
curl --manual # portable way