cURL Fundamentals

API Testing & Tooling — cURL Fundamentals
API Testing & Tooling
Chapter 6 · cURL Fundamentals

💻 cURL Fundamentals

Chapter 1 named cURL as the tool for when there's no GUI at all — SSH sessions, shell scripts, CI runners. This chapter builds the same requests as Chapters 2–5, this time as single terminal commands that work identically on any machine with a shell.

The Basic Shape of a cURL Command

With no options at all, curl sends a GET request and prints the response body to the terminal:

curl https://api.example.com/products/42

Specifying the HTTP Method

The -X flag sets the method explicitly — needed for anything other than a plain GET:

curl -X POST https://api.example.com/products curl -X DELETE https://api.example.com/products/42

Headers

-H adds a header — one -H per header, repeated as many times as needed:

curl -H "Authorization: Bearer eyJhbGci..." -H "Accept: application/json" https://api.example.com/me

Sending Data: -d / --data

-d attaches a request body — and using -d at all implicitly switches the method to POST if -X wasn't specified:

curl -X POST https://api.example.com/products \ -H "Content-Type: application/json" \ -d '{"name": "Wireless Mouse", "price": 24.99}'

Seeing What's Actually Happening: -i and -v

By default, curl only prints the response body. Two flags reveal more: -i includes the response headers above the body (status code included); -v (verbose) shows the entire exchange — the request curl actually sent, connection details, and the full response — the closest cURL equivalent to Postman's full request/response inspection.

Default Output vs. -i vs. -v

Default

Just the response body — no status code, no headers visible at all.

-i

Status line and response headers, then the body — enough to check "did this actually succeed" without full verbosity.

-v goes further still, printing the request headers curl sent (prefixed with >) and the response headers received (prefixed with <) — invaluable when a request behaves unexpectedly and you need to confirm exactly what was actually sent, not just what you intended to send.

Following Redirects: -L

By default, curl does not follow a 3xx redirect — it prints the redirect response itself (a 301/302 with a Location header) and stops there. The -L flag tells curl to follow it automatically and fetch the final destination instead.

curl -i https://example.com/old-path # shows the 301 itself, doesn't follow it curl -iL https://example.com/old-path # follows the redirect, shows the final response

Basic Auth: -u

-u user:password handles HTTP Basic Authentication — curl base64-encodes the credentials and sets the Authorization: Basic ... header automatically, no manual encoding required.

curl -u admin:secretpass https://api.example.com/admin/stats
FlagPurpose
-X METHODSet the HTTP method explicitly
-H "Header: value"Add a request header (repeatable)
-d / --dataAttach a request body; implies POST if no -X given
-iInclude response status line and headers in the output
-vVerbose — show the full request and response, including connection details
-LFollow redirects automatically
-u user:passSend HTTP Basic Authentication credentials

Putting It Together

curl -iL -X POST https://api.example.com/products \ -H "Content-Type: application/json" \ -H "Authorization: Bearer eyJhbGci..." \ -d '{"name": "Wireless Mouse", "price": 24.99}'

One command: method, two headers, a JSON body, redirect-following, and status/headers visible in the output — everything Chapters 2–3 needed several Postman UI fields for, expressed as flags on a single line.

💻 Coding Challenges

Challenge 1: Write the cURL Command

Write a cURL command that sends a DELETE request to https://api.example.com/orders/55 with an Authorization: Bearer abc123 header, and shows the response status code in the output.

Goal: Practice combining -X, -H, and -i in one command.

→ Solution

Challenge 2: Diagnose Missing Output

A developer runs curl https://api.example.com/old-report and sees an empty response body, even though they're sure the endpoint has data. Using this chapter's material, what's the most likely explanation, and what single flag would confirm it?

Goal: Practice recognizing an unfollowed redirect as a concrete real-world symptom, not just an abstract flag definition.

→ Solution

Challenge 3: -i vs. -v

A teammate wants to confirm the exact Content-Type header their own script actually sent (not just what they intended to send). Should they reach for -i or -v? Justify your answer.

Goal: Practice distinguishing what each flag actually reveals — response-only versus full request-and-response.

→ Solution

⚠️ Gotcha: -d Without the Right Content-Type Sends the Wrong Format

Running curl -d '{"name": "Wireless Mouse"}' https://api.example.com/products looks like it's sending JSON — but without an explicit -H "Content-Type: application/json", curl defaults -d's Content-Type to application/x-www-form-urlencoded, the format HTML forms use. A JSON-expecting API may then either reject the request outright or, worse, silently misinterpret the body without erroring at all. This is the exact same failure mode Chapter 2's Postman gotcha described for a raw body sent with the wrong format dropdown — always pair -d with an explicit Content-Type header when the body is JSON, never rely on curl's default.

🎯 What's Next

The next chapter is cURL Advanced — bearer tokens and API keys in practice, file uploads with -F, piping JSON output through jq for readability, and saving/replaying requests as scripts.