cURL (Client URL) is a command-line tool for making HTTP requests. It's installed on virtually every Unix-like system and available on Windows — and once you know the core flags, it becomes your go-to tool for testing APIs, debugging requests, and scripting HTTP interactions without spinning up a GUI client.
Don't want to memorise the flags? The DevToolShack cURL Generator builds the command for you — fill in the URL, method, headers, and body, and copy a ready-to-run cURL command.
The Simplest Request
A bare cURL command makes a GET request and prints the response body:
curl https://api.example.com/users
That's it. The response body prints to stdout. Redirect it to a file with > output.json if you want to save it.
Essential Flags to Know
| Flag | What it does |
|---|---|
-X METHOD | Specify HTTP method (GET, POST, PUT, DELETE, PATCH) |
-H "Header: Value" | Add a request header (repeat for multiple) |
-d "data" | Send request body data |
-i | Include response headers in output |
-I | Fetch headers only (HEAD request) |
-o filename | Save output to a file |
-s | Silent mode — suppress progress meter |
-v | Verbose — show full request and response details |
-L | Follow redirects |
-u user:pass | Basic authentication |
-k | Skip SSL certificate verification (dev only!) |
--max-time N | Timeout after N seconds |
Common API Patterns
GET with Authorization Header
curl https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
POST with JSON Body
curl -X POST https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Ada Lovelace", "email": "ada@example.com"}'
-H "Content-Type: application/json", the server may not parse your JSON body correctly and you'll get mysterious 400 errors. The Content-Type header tells the server how to interpret the request body.PUT to Update a Resource
curl -X PUT https://api.example.com/users/42 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Ada Lovelace", "role": "admin"}'
DELETE a Resource
curl -X DELETE https://api.example.com/users/42 \
-H "Authorization: Bearer YOUR_TOKEN"
Sending a File
# Upload a file as multipart form data
curl -X POST https://api.example.com/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@/path/to/file.pdf" \
-F "description=My document"
Debugging Requests
The -v flag (verbose) is your best debugging ally — it shows the full request, including headers sent, the TLS handshake, redirect chain, and response headers:
curl -v https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN"
# Output includes:
# * Trying 93.184.216.34:443...
# * Connected to api.example.com
# > GET /users HTTP/2
# > Host: api.example.com
# > Authorization: Bearer YOUR_TOKEN
# < HTTP/2 200
# < content-type: application/json
# ...
The > lines are the outgoing request. The < lines are the incoming response. This is the fastest way to verify that headers are being sent correctly.
Pretty-Printing JSON Responses
cURL outputs raw JSON — hard to read for complex responses. Pipe through Python's json.tool or jq for instant pretty-printing:
# Using Python (available everywhere)
curl -s https://api.example.com/users | python3 -m json.tool
# Using jq (install separately — worth it)
curl -s https://api.example.com/users | jq .
# jq also lets you extract specific fields
curl -s https://api.example.com/users | jq '.[0].name'
Or paste the raw JSON response into the JSON Formatter for an instant readable view without any terminal tooling.
Saving and Reusing Commands
For frequently-used API calls, save cURL commands as shell aliases or scripts:
# Add to ~/.bashrc or ~/.zshrc
alias api-users='curl -s https://api.example.com/users \
-H "Authorization: Bearer $API_TOKEN" | python3 -m json.tool'
# Store the token as an environment variable — never hardcode it
export API_TOKEN="your-token-here"
cURL vs Postman vs Insomnia
GUI tools like Postman and Insomnia are great for exploration and team sharing. cURL wins when:
- You're on a server with no GUI
- You need to script or automate requests
- You want to share a reproducible request with someone (cURL commands are universal)
- You're debugging and want to eliminate all browser/client variables
- You need to integrate API calls into shell scripts or CI pipelines
Many API docs provide cURL examples specifically because it's the lowest common denominator — if it works in cURL, you know the API itself is working and the problem is elsewhere.