What Is the curl Command? Examples, Flags, HTTP Requests
curl sends HTTP requests from the terminal. Learn the syntax, the most used flags, recipes for APIs, common mistakes and when to use another tool.
What is the curl command?
curl is a command-line tool that transfers data to or from a server using a URL. Most developers use it to send HTTP requests from the terminal: call an API, inspect headers and status codes, upload a file or script a quick check. One short command shows exactly what a client sent and what the server answered.
It began in 1996 as a small tool called HttpGet, was renamed curl in 1998 and is maintained by Daniel Stenberg. Besides HTTP and HTTPS it speaks FTP, SFTP, SMTP, IMAP and many other protocols. The full option list is in the curl man page.
Basic curl syntax
The simplest command sends a GET request and prints the response body:
curl https://api.example.com/users/42Add -i to see the status line and response headers too:
curl -i https://api.example.com/users/42Giving curl data with -d makes it a POST by default, so -X POST is optional. The data is sent as application/x-www-form-urlencoded, so for JSON you must set the header yourself:
curl -X POST https://api.example.com/users -H "Content-Type: application/json" -d '{"name": "Alice", "email": "alice@example.com"}'Since curl 7.82.0 the --json option does this in one step: it sends the data as a POST with the JSON Content-Type and Accept headers, without checking that the JSON is valid.
curl --json '{"name": "Alice"}' https://api.example.com/usersMost used curl flags
| Flag | What it does |
|---|---|
-X METHOD | Set a custom HTTP method such as PUT or DELETE. Normally not needed for GET, HEAD and POST |
-H "Name: value" | Add a request header |
-d 'data' | Send a request body (POST). -d @file.json reads it from a file |
--data-raw | Like -d, but a leading @ is not treated as a file name |
--json | POST JSON with the right headers (7.82.0 and later) |
-F "field=value" | Send a multipart/form-data field; -F "file=@photo.jpg" uploads a file |
-i / -I | Show response headers / send a HEAD request and show only headers |
-L | Follow redirects |
-o file / -O | Save the body to a named file / to a file named like the remote one |
-s | Silent mode: no progress meter |
-v | Verbose output, to debug what is sent and received |
-k | Skip TLS certificate verification (testing only) |
-u user:pass | HTTP Basic authentication |
-m N / --max-time N | Give up after N seconds in total |
--fail | Exit with code 22 on an HTTP status of 400 or higher |
-w format | Print values such as the status code or timings after the transfer |
Common curl recipes
Test an API endpoint
Hit an API endpoint and read the status line and headers:
curl -i https://api.example.com/healthSend a token
Pass a bearer token in the Authorization header. Use double quotes so the shell expands $TOKEN:
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/orders/42Upload a file
-F sends a multipart/form-data request:
curl -F "avatar=@photo.jpg" -F "username=alice" https://api.example.com/uploadPrint only the status code
curl -s -o /dev/null -w "%{http_code}\n" https://example.comMeasure response time
The write-out variables give you timings for one request, including time to first byte:
curl -s -o /dev/null -w "ttfb %{time_starttransfer}s total %{time_total}s\n" https://example.comCommon curl mistakes
- Forgetting the JSON Content-Type. With plain
-dthe body goes out as form data and many APIs answer 400 or 415. Add the header or use--json. Our post on how parameters are sent in an HTTP POST request explains the three body formats. - Adding
-X POSTto every-d. It is redundant, and-Xkeeps the method even after a redirect, which can hide the real behavior. - Quoting. In bash, single quotes around JSON protect the double quotes inside, but they also stop
$TOKENfrom expanding. Windows cmd needs double quotes with escaping. - Secrets in history. A token typed after
-Hlands in your shell history. Read it from an environment variable or a file. - Trusting the exit code. By default curl treats a 404 or 500 as a successful transfer. In scripts add
--fail, and use--fail-with-bodyif you also want the body. - Leaving
-kin a script. It turns off certificate checks, so a man-in-the-middle goes unnoticed. - Forgetting
-L. Without it curl stops at the first 301 or 302.
curl in API testing, CI and monitoring
Because curl is on most machines, it is the quickest way to reproduce a failing call and the usual building block for API testing in a pipeline. A smoke test after a deploy can be one line, with a timeout and --fail so a bad status fails the build:
curl --fail --max-time 10 -s -o /dev/null https://example.com/health- No terminal at hand? The free curl Online tool works like curl in the browser: send GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS requests and read the status, headers, body, certificate and timing breakdown. Safe methods run from six AWS regions so you can compare them.
- Turn a command into a test. The cURL to k6 converter turns a curl command into a k6 script, and the post on importing cURL, HAR, Postman or OpenAPI into load tests covers the other formats.
- Keep checking after the deploy. A curl in cron is easy to write and easy to forget. API monitoring runs the request on a schedule from several locations, checks status, body, headers and response time, and alerts you. The free plan checks every 5 minutes on LoadFocus API monitoring.
- Not a load testing tool.
--parallel(curl 7.66.0 and later) runs transfers concurrently, up to 50 at a time by default. It reports each transfer, not percentiles, ramp-up or results by region, and it comes from one machine. For real traffic use load testing from cloud regions.
FAQ: curl command
What is the difference between -d and --data-raw?
With -d, a value that starts with @ is read as a file name. With --data-raw, the same value is sent literally. Use --data-raw when your data really starts with an @ character.
How do I send a custom HTTP method?
Use -X, for example curl -X PUT or curl -X DELETE. You normally do not need -X for GET, HEAD or POST, because curl picks the method from the other options.
How do I see exactly what curl sends?
Add -v for verbose output. It prints the request headers curl sent, the response headers it received and details of the TLS connection.
How do I keep cookies across several curl calls?
Save them with -c cookies.txt (cookie jar) on the first call and send them with -b cookies.txt on the next calls.
Can curl run requests in parallel?
Yes. Since 7.66.0 the --parallel (-Z) option runs several transfers at once, 50 at a time by default, and --parallel-max changes that. It is handy for downloads, but it is not a substitute for a load test.
Can I use curl as a load testing tool?
For a handful of concurrent requests, yes. It does not aggregate results into percentiles, ramp users up or run from several regions. For that, convert the call to a k6 or JMeter test and run it from the cloud.
Related terms
- What is the History API?
- What is Idempotency? HTTP Methods, Idempotency Keys, Examples
- What is JSON? Beginner's Guide with Syntax, Examples
- What is JSON-RPC? Protocol, Examples, REST Comparison
- What is multipart/form-data Content-Type? File Uploads, Examples
- What is Swagger? Swagger vs OpenAPI Explained
- CRUD Operations: Create, Read, Update, Delete Explained
- What Are API Attacks?
Related LoadFocus Tools
Put this concept into practice with LoadFocus, the same platform that powers everything you just read about.