What You'll Learn
- What cURL is and why every developer uses it
- The 10 cURL commands you'll use daily
- How to send headers, bodies, and authentication
- How to debug requests with verbose output
Why This Matters
cURL is the universal API client. It runs on every operating system, supports every HTTP feature, and is the language of API documentation — when docs show "how to call this endpoint", they almost always show a cURL command. Master cURL and you can call any API from any terminal.
Simple Explanation
cURL (Client URL) is a command-line tool for transferring data with URLs. It supports HTTP, HTTPS, FTP, and dozens of other protocols. For API work, you use it to send HTTP requests and print the responses.
Your First cURL Command
curl https://api.open-meteo.com/v1/forecast?latitude=19.07&longitude=72.87¤t=temperature_2m
cURL sends a GET request and prints the response body to your terminal. That is the simplest case.
& break in shells because & means "run in background". Always write: curl "https://api.example.com?a=1&b=2"
The 10 Commands You'll Use Daily
1. GET request
curl https://jsonplaceholder.typicode.com/posts/1
2. GET with response headers (-i)
curl -i https://jsonplaceholder.typicode.com/posts/1
-i includes the HTTP status line and headers in the output.
3. GET with verbose output (-v)
curl -v https://jsonplaceholder.typicode.com/posts/1
-v prints everything: the request being sent, the response being received, and connection details. Use this for debugging.
4. GET headers only (-I)
curl -I https://jsonplaceholder.typicode.com/posts/1
-I (capital I) fetches only headers — useful for checking content type, cache headers, etc.
5. POST with JSON body
curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title":"hello","body":"world","userId":1}'
-X POST sets the method. -H adds a header. -d sends the body.
6. PUT (replace)
curl -X PUT https://jsonplaceholder.typicode.com/posts/1 \
-H "Content-Type: application/json" \
-d '{"id":1,"title":"new title","body":"new body","userId":1}'
7. PATCH (partial update)
curl -X PATCH https://jsonplaceholder.typicode.com/posts/1 \
-H "Content-Type: application/json" \
-d '{"title":"patched title"}'
8. DELETE
curl -X DELETE https://jsonplaceholder.typicode.com/posts/1
9. With authentication (Bearer token)
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/users/me
10. With a request body from a file
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d @payload.json
The @ prefix tells cURL to read the body from a file. Useful for large payloads.
Useful cURL Flags
| Flag | What it does |
|---|---|
-X METHOD | Set the HTTP method (GET is default) |
-H "Name: Value" | Add a request header |
-d "data" | Send data in the body |
-d @file | Send body from a file |
-i | Include response headers in output |
-I | Fetch headers only |
-v | Verbose — show full exchange |
-o file | Save response to a file |
-L | Follow redirects (3xx) |
-k | Skip SSL certificate verification (for testing only) |
-u user:pass | Basic authentication |
--max-time N | Timeout after N seconds |
-w "%{http_code}" | Print just the HTTP status code |
Reading Verbose Output
curl -v https://jsonplaceholder.typicode.com/posts/1
Output (truncated):
* Trying 172.67.222.21...
* Connected to jsonplaceholder.typicode.com (172.67.222.21) port 443 (#0)
> GET /posts/1 HTTP/1.1 <-- request line (sent by client)
> Host: jsonplaceholder.typicode.com
> User-Agent: curl/7.81.0
> Accept: */*
> <-- blank line ends headers
< HTTP/1.1 200 OK <-- response status line (from server)
< Content-Type: application/json; charset=utf-8
< Content-Length: 292
< <-- blank line ends response headers
{
"userId": 1,
"id": 1,
"title": "sunt aut facere...",
"body": "quia et suscipit..."
}
Lines starting with > are the request. Lines starting with < are the response. Lines starting with * are cURL's connection info.
Common Mistakes
- Not quoting URLs.
curl https://api.example.com?a=1&b=2breaks because the shell interprets&. Always quote:curl "https://...". - Forgetting
-H "Content-Type: application/json"when sending JSON. The server does not know your body is JSON without it. - Using single quotes for the body on Windows. Windows cmd does not handle single quotes the way bash does. Use double quotes and escape inner quotes, or use Postman on Windows.
- Confusing
-iand-I. Lowercase includes headers + body. Uppercase fetches headers only. - Not using
-vwhen debugging. If a request fails,-vshows you exactly what was sent and received. - Using
-kin production.-kskips certificate verification — only for local testing.
Practical Exercise (15 minutes)
- GET post 1 from JSONPlaceholder. Note the title.
- POST a new post with a title and body. Note the ID returned.
- PUT to replace post 1 with new content.
- PATCH post 1 to update only the title.
- DELETE post 1.
- Use
-von one of the above to see the full HTTP exchange. - Use
-Ito fetch only the headers of post 1.
Mini Challenge
Write a single cURL command that: calls https://api.github.com/repos/microsoft/vscode, sends an Accept: application/json header, saves the response to a file called repo.json, and prints only the HTTP status code to the terminal. (Hint: combine -o, -H, and -w.)
Key Takeaways
- cURL is the universal command-line API client. Every API doc shows cURL examples.
- Quote URLs to avoid shell issues with
&. - Key flags:
-Xmethod,-Hheader,-dbody,-iinclude headers,-vverbose,-osave to file. - Always set
Content-Type: application/jsonwhen sending a JSON body. - Use
-vto debug any failing request — it shows the full exchange.
Previously: Lesson 22 covered calling APIs from a browser.
Today: You learned cURL — the universal command-line API client.
Next: Lesson 24 introduces Postman, a GUI API client that's friendlier than cURL for complex requests.
FAQ
Is cURL installed by default?
Yes on macOS and most Linux distributions. On Windows 10+, cURL is included but aliased to Invoke-WebRequest in PowerShell — use curl.exe explicitly to get the real cURL. Or install Git Bash, which includes cURL.
Should I learn cURL if I have Postman?
Yes. cURL is faster for quick one-off tests, works on any server (including SSH sessions), and is what API docs show. Postman is better for collections and complex workflows. Use both.
Comments
Comments
Post a Comment