cURL Command Reference for API Testing

cURL is the fastest way to test an API endpoint from a terminal — no GUI, no project setup, and every request is copy-pasteable into a script, a bug report, or CI. This reference covers the flags used for real day-to-day API testing, not the full (enormous) cURL manual.

Key Takeaways

  • -X sets the HTTP method; it defaults to GET if omitted and is only needed to override that
  • -H adds a header (repeat the flag for multiple headers); -d sends a request body and implies POST if -X isn't set
  • -i includes response headers in the output; -v shows the full request/response exchange for debugging
  • -o saves the response body to a file; -s silences the progress meter (useful when piping output elsewhere)
  • A curl command is a precise, shareable artifact — pasting one into a bug report is often clearer than describing the request in words

Basic GET request

A bare curl <url> sends a GET request and prints the response body to stdout. Add -i to include response headers, which is usually the first thing worth checking when a response looks wrong — the status code and content-type header often explain the issue before you even read the body.

GET with headers shown
curl -i https://api.example.com/users/42

Setting the HTTP method

-X <METHOD> overrides the default GET. Note that -X is technically unnecessary when sending a body with -d, since -d implies POST — but including -X explicitly makes the command's intent unambiguous to anyone reading it later.

POST, PUT, DELETE
curl -X POST https://api.example.com/users
curl -X PUT https://api.example.com/users/42
curl -X DELETE https://api.example.com/users/42

Sending headers and a JSON body

-H "<Header>: <value>" adds a request header — repeat -H for each additional header. -d '<data>' sends a request body; for JSON APIs, always pair it with -H "Content-Type: application/json" so the server parses the body correctly rather than treating it as form-encoded data.

POST JSON with headers
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"name": "Ada", "role": "admin"}'

Authentication

Bearer tokens go in an Authorization header as shown above. Basic auth can be sent directly with -u user:password, which curl encodes correctly — never hand-construct the Base64-encoded Authorization header yourself when -u does it correctly in one step.

Basic auth
curl -u username:password https://api.example.com/protected

Inspecting the full exchange

-v (verbose) shows the entire request and response, including headers, TLS handshake info, and timing — this is the fastest way to debug a mysterious failure, since it shows exactly what was sent, not just what you intended to send. Combine with -s (silent) to suppress the separate progress meter when you only want the -v output.

Full verbose debug
curl -sv https://api.example.com/users/42

Saving output and following redirects

-o <file> writes the response body to a file instead of stdout (useful for downloading or for large responses you want to inspect in an editor). -L makes curl follow redirects automatically — without it, a 3xx response is shown as-is rather than being followed to its final destination.

Save response, follow redirects
curl -L -o response.json https://api.example.com/users/42

Common Mistakes to Avoid

  • Sending a JSON body with -d but forgetting the Content-Type: application/json header, causing the server to misparse it
  • Hand-encoding Basic Auth credentials instead of using -u, which handles the encoding correctly
  • Not using -L and being confused when a redirected request "doesn't work" — the un-followed redirect response was the actual (correct) result
  • Forgetting -i or -v when debugging, and only ever looking at the response body without the status code or headers
  • Pasting a curl command containing a real bearer token or password into a shared bug report or chat channel

Frequently Asked Questions

Do I need -X POST if I'm already sending data with -d?

Technically no — curl infers POST automatically when -d is present. Many developers include -X POST anyway for clarity, since it makes the command's intent explicit to anyone reading it later without having to know that inference rule.

Why is my POST request body not being parsed correctly by the server?

The most common cause is a missing or incorrect Content-Type header. If you're sending JSON with -d, pair it with -H "Content-Type: application/json" — without it, some servers will try to parse the body as URL-encoded form data instead.

How do I see exactly what curl sent and received, not just the final body?

Use the -v (verbose) flag, which prints the full request line, all request and response headers, and connection details. It's the fastest way to diagnose an API call that isn't behaving as expected.

Last reviewed: 2026 · Written and verified by the Dev Utilities team · Editorial policy

Report an issue with this guide →