Overview
curl is the fastest way to test an HTTP endpoint before writing client code. Pipe responses to jq-syntax; status meanings are in http-status-codes. Always quote URLs that contain & or ?.
Request
State method, headers, and body explicitly when testing an API.
| Flag | Effect |
|---|---|
-X PUT | Set the method (also PATCH, DELETE). Unnecessary with -d, which implies POST. |
-H "Accept: application/json" | Add a header. |
--json '{"a":1}' | POST JSON and set Content-Type and Accept (curl 7.82+). |
-d '{"a":1}' | POST a body as application/x-www-form-urlencoded. |
-d @f.json / --data-binary @f.json | Body from a file: strips newlines / sends bytes exactly (add -H "Content-Type: image/png" for a binary PUT). |
--data-raw '@x' | Send a leading @ literally. |
--data-urlencode "q=a b" | Encode one form field. |
-G -d "q=test" | Move -d data into the query string. |
-F "file=@a.jpg;type=image/jpeg" | Multipart upload; repeat -F for fields. |
Output
Use --fail-with-body in scripts so server errors fail loudly and stay readable.
| Flag | Effect |
|---|---|
-I / -i / -D - | Headers only (HEAD) / headers plus body / dump headers to stdout. |
-v / --trace-ascii - | Request and response detail / full wire trace. |
-o f / -O | Save the body to f / to the URL’s filename. |
-s / -S | Silent / still show errors. |
--fail | Exit 22 on 4xx or 5xx and print no body. |
--fail-with-body | Exit 22 on 4xx or 5xx but print the body (7.76+). |
-w "%{http_code}\n" | Print a write-out variable after the transfer. |
--retry 3 --retry-delay 2 | Retry transient failures; add --retry-all-errors for more. |
--max-time 10 / --connect-timeout 5 | Overall / connect-phase limit in seconds. |
--compressed | Request compressed content and decode it. |
-C - -o f | Resume a download. |
Redirects, TLS, proxy
Fix certificate problems with --cacert; avoid -k outside local debugging.
| Flag | Effect |
|---|---|
-L / --max-redirs 5 | Follow redirects / cap the chain. |
--resolve example.com:443:127.0.0.1 | Override DNS for one host (test before DNS changes). |
--cacert ca.pem | Trust a private CA. |
--cert c.pem --key c.key | Mutual TLS. |
-k | Skip all certificate verification; local debugging only. |
-x http://proxy:8080 / --noproxy localhost | Use a proxy / bypass it. |
Auth and cookies
Keep credentials out of the command line and shell history.
| Flag | Effect |
|---|---|
-H "Authorization: Bearer $TOKEN" | Bearer token; --oauth2-bearer $TOKEN is equivalent. |
-u user:pass / -u user | Basic auth (Base64, not encrypted; use HTTPS) / prompt for the password. |
-H "X-API-Key: $KEY" | API-key header; the name varies by service. Avoid keys in query strings, which URLs log. |
--digest -u user:pass | Digest auth. |
-b "a=1" / -b jar.txt -c jar.txt | Send a cookie / read and save a cookie jar. |
--netrc-file f | Credentials from a netrc file. |
Recipes
Copy and adapt these; swap in your URL and token variable.
curl -sS https://api.example.com/users | jq . # GET + pretty-print
curl -sS --json '{"name":"alice"}' https://api.example.com/users # POST JSON
curl -sS -X PUT -H "Authorization: Bearer $TOKEN" \
--json '{"name":"bob"}' https://api.example.com/users/1 # PUT with auth
curl -o /dev/null -sS -w "%{http_code}\n" https://api.example.com/health
curl -s -o /dev/null -w 'dns %{time_namelookup} connect %{time_connect} ttfb %{time_starttransfer} total %{time_total}\n' https://example.com
curl -F "file=@photo.jpg" -F "title=Photo" https://api.example.com/uploadGotchas
Avoid these; each hides a failed request or sends the wrong body.
| Gotcha | Fix |
|---|---|
Without --fail, curl exits 0 on 404 and 500, so scripts miss errors. | Use --fail-with-body or check %{http_code}. |
-d sends form encoding, not JSON. | Use --json, or add the Content-Type header. |
-d @file strips newlines. | Use --data-binary @file for exact bytes. |
-L -d turns POST into GET after a 301, 302, or 303. | --post301, --post302, --post303 keep POST; -X POST forces it on every hop. |
-L drops Authorization on a cross-host redirect. | --location-trusted sends it; use only for trusted targets. |
-w output lands right after the body with no newline. | Add \n or send the body to -o /dev/null. |
-u and bearer tokens appear in the process list and shell history. | Prompt with -u user, read from a netrc file, or use an env var. |