curl Basics

curl is the Swiss Army knife of HTTP. Test APIs, download files, debug connections - all from the terminal.

Basic Request

Terminal
$curl https://example.com
<!doctype html> <html> <head> <title>Example Domain</title>...

This makes a GET request and prints the response body.

Save to File

Terminal
$curl -o page.html https://example.com
(saves to page.html)
$curl -O https://example.com/file.pdf
(saves as file.pdf - uses remote filename)

-o specifies filename, -O uses the remote filename.

Show Headers

Terminal
$curl -I https://example.com
HTTP/2 200 content-type: text/html; charset=UTF-8 date: Tue, 14 Jan 2025 10:30:45 GMT cache-control: max-age=604800

-I (HEAD request) shows only headers.

Terminal
$curl -i https://example.com
HTTP/2 200 content-type: text/html <!doctype html>...

-i includes headers WITH body.

Verbose Output

Terminal
$curl -v https://example.com
* Trying 93.184.216.34:443... * Connected to example.com > GET / HTTP/2 > Host: example.com > User-Agent: curl/7.68.0 < HTTP/2 200 < content-type: text/html ...

-v shows the full request/response conversation. Essential for debugging.

POST Requests

Terminal
$curl -X POST -d 'name=john&email=john@example.com' https://api.example.com/users
{"status": "created"}

-X POST specifies method, -d sends data.

JSON POST

Terminal
$curl -X POST \
$ -H 'Content-Type: application/json' \
$ -d '{"name": "john", "email": "john@example.com"}' \
$ https://api.example.com/users
{"id": 123, "name": "john"}

JSON APIs

Always set Content-Type: application/json for JSON APIs. Many APIs reject requests without it.

Custom Headers

Terminal
$curl -H 'Authorization: Bearer TOKEN123' \
$ -H 'Accept: application/json' \
$ https://api.example.com/me
{"user": "john"}

Follow Redirects

Terminal
$curl http://google.com
(HTML redirect page)
$curl -L http://google.com
(follows redirect, shows final page)

-L follows redirects automatically.

Timeout

Terminal
$curl --connect-timeout 5 https://slow-server.com
(fails after 5 seconds if can't connect)

Status Code Only

Terminal
$curl -s -o /dev/null -w '%{http_code}' https://example.com
200

-s silent, -o /dev/null discard body, -w print status code.

Testing APIs

Terminal
$# GET
$curl https://api.github.com/users/octocat
{"login": "octocat", ...}
$
$# POST with JSON
$curl -X POST -H 'Content-Type: application/json' -d '{"key": "value"}' URL
$
$# PUT
$curl -X PUT -d 'data' URL
$
$# DELETE
$curl -X DELETE URL
Knowledge Check

How do you make a JSON POST request with curl?

Quick Reference

FlagPurpose
-o fileSave to file
-OSave with remote filename
-IHeaders only (HEAD request)
-iInclude headers in output
-vVerbose (debug)
-X METHODSpecify HTTP method
-d dataSend data (POST body)
-H headerCustom header
-LFollow redirects
-sSilent mode

Key Takeaways

  • curl URL makes a GET request
  • -I for headers, -v for debugging
  • -X POST -d 'data' for POST requests
  • Always set Content-Type header for JSON APIs
  • -L follows redirects
  • Incredibly useful for API testing

Next: downloading files with wget.