Silent mode — suppress the progress meter and most error messages. Pairs well with scripts.
⚠ Common pitfall: `-s` also silences real errors. Pair with `-S` to still see errors: `curl -sS …`. Otherwise a 500 silently returns empty.
Examples
curl -s https://api.example.com/health
curl -sS https://api.example.com/health | jq .
curl -o <file> <url>
Write the response body to <file> instead of stdout (you choose the name).
Examples
curl -o page.html https://example.com
curl -o image.png https://example.com/img.png
curl -O <url>
Save the file using the remote filename (the last path segment of the URL).
⚠ Common pitfall: If the server redirects (e.g. /latest → /v1.2.3/foo.zip) you get a file literally named "latest". Add -L -J to honor Content-Disposition.
Print the curl version, the TLS / SSH backend it was built with, and the list of supported protocols and features.
⚠ Common pitfall: The "Features:" line tells you whether your build has HTTP2, HTTP3, brotli, etc. If a flag fails, check here before blaming the flag.
Examples
curl --version
curl --version | grep -i http2
curl -sS -f <url>
The script-safe combo: -s hides the progress bar, -S keeps real errors, -f makes curl exit non-zero on HTTP 4xx/5xx instead of printing the error page.
⚠ Common pitfall: -f swallows the response body on error, so you lose the error JSON. Use --fail-with-body (curl 7.76+) to fail AND still print the body.
Examples
curl -sSf https://api.example.com/health || echo down
Send a POST with a request body. With -d the Content-Type defaults to application/x-www-form-urlencoded.
⚠ Common pitfall: For JSON you MUST set the header: `-H "Content-Type: application/json"`. Many APIs 415 you otherwise because they treat it as form data.
Examples
curl -X POST -d "user=lei&pwd=123" https://api.example.com/login
curl -X POST -H "Content-Type: application/json" -d '{"q":"hi"}' https://api.example.com/chat
curl -X PUT -d <body> <url>
Replace the resource at <url> with the supplied body. Common for REST update endpoints.
Examples
curl -X PUT -H "Content-Type: application/json" -d '{"name":"Lei","age":30}' https://api.example.com/users/1
curl -X PATCH -d <body> <url>
Send a partial update. The body contains only the fields you want to change.
Shorthand (curl 7.82+) for sending a JSON body: sets Content-Type AND Accept to application/json and POSTs the data. Equivalent to -d + two -H.
⚠ Common pitfall: --json does NOT url-encode and implies POST. Repeating --json concatenates the chunks, so you can split a body across flags or read from @file.
Multipart field whose VALUE is read from a file (the `<` form), but sent as a normal text field, not as a file upload attachment.
⚠ Common pitfall: `@file` uploads as a file part (with filename + binary). `<file` inlines the file content as the text value of the field. Different parts on the wire.
URL-encode the ENTIRE file content and send it as the body. Unlike `key@file`, no field name is prepended.
⚠ Common pitfall: `--data-urlencode "name@file"` encodes the file as the value of `name`. `--data-urlencode "@file"` encodes the file with no key at all.
Send a POST with an empty (zero-length) body. Some APIs require an explicit empty POST to trigger an action.
⚠ Common pitfall: This is the correct way to POST nothing — unlike `-X POST` alone, `-d ""` actually sets Content-Length: 0 and the POST method together.
Override the Host header to test a specific virtual host on a server, while pinning the IP with --resolve.
⚠ Common pitfall: For HTTPS, the TLS SNI comes from the URL hostname, not the Host header. To also override SNI use --connect-to or put the real name in the URL.
Follow HTTP 3xx redirects to the final URL. Without -L curl prints the tiny redirect body and stops.
⚠ Common pitfall: By default -L does NOT re-send Authorization / Cookie headers to a different host. Use --location-trusted if you really need to.
Examples
curl -L https://bit.ly/short-url
curl -LI https://github.com/cli/cli/releases/latest # see the full chain
curl -L --max-redirs <n> <url>
Cap how many redirects curl will follow. Default is 50, set to 0 to disable, -1 for unlimited.
Examples
curl -L --max-redirs 5 https://example.com/a
curl -L --max-redirs 0 https://example.com/x # error if any redirect
curl --location-trusted <url>
Like -L, but DO forward the Authorization header when the redirect target is on a different host.
⚠ Common pitfall: Sending credentials to an attacker-controlled redirect destination is the whole reason -L drops them by default. Use only with trusted endpoints.
Keep the original method + body across redirects instead of letting curl downgrade POST to GET on a 301/302/303.
⚠ Common pitfall: RFC behavior: many clients turn POST into GET on 301/302. These flags force curl to re-POST. 308 / 307 already preserve the method by spec.
How long curl waits for a 100-continue response before sending the body anyway. Tune this when a slow server stalls large PUT/POST uploads.
⚠ Common pitfall: curl auto-adds `Expect: 100-continue` for large bodies. If the server ignores it, curl waits this timeout (default 1s) then sends anyway.
Pin a hostname to a specific IP for this request only. Skip DNS entirely.
⚠ Common pitfall: Perfect for testing a new server before changing DNS, or hitting a specific node behind a load balancer. SNI is set from the URL hostname, not the IP.
Restrict the TLS cipher suites curl offers. Needed to talk to legacy servers stuck on old ciphers, or to test a specific suite.
⚠ Common pitfall: For TLS 1.3 suites use --tls13-ciphers (a separate flag). `--ciphers DEFAULT@SECLEVEL=1` relaxes OpenSSL's security level for old servers.
Stream a download straight into a decompressor instead of writing an intermediate file. Common for installing tarballs.
⚠ Common pitfall: Piping curl | sh is a real supply-chain risk — you run whatever the server returns. Inspect first, or download then verify a checksum.
Examples
curl -sL https://example.com/release.tar.gz | tar xz -C /opt
Upload a file with HTTP PUT (or FTP STOR / SCP / SFTP depending on URL scheme).
⚠ Common pitfall: `-T file http://host/dir/` (trailing slash) uploads to host/dir/<file>. Without trailing slash, the URL is the exact destination path.
DNS failed for the hostname. Check spelling, DNS config (/etc/resolv.conf), and that you are not behind a captive portal.
⚠ Common pitfall: Inside Docker on Linux, the default DNS is 127.0.0.11 (embedded). If you set --network host you inherit host DNS.
Examples
dig example.com
curl --resolve example.com:443:1.2.3.4 https://example.com # bypass DNS
curl: (7) Failed to connect / Connection refused
TCP could not connect. The host is up but no process is listening on that port — or a firewall is blocking it.
⚠ Common pitfall: On macOS / Linux, check with `lsof -i :<port>` or `ss -tlnp`. In Docker, did you publish the port (-p) and is the app binding 0.0.0.0 not 127.0.0.1?
Examples
ss -tlnp | grep :8080
docker run -p 8080:80 nginx # publish
curl: (28) Operation timed out
Either the connect or the transfer timed out. Add --connect-timeout and --max-time to set tight bounds + faster failure.
TLS could not negotiate. Common causes: missing SNI, server requires TLS 1.2+ but client tries TLS 1.0, or cipher mismatch.
⚠ Common pitfall: Test with `openssl s_client -connect host:443 -servername host`. Try `--tls-max 1.2` or `--ciphers DEFAULT@SECLEVEL=1` for legacy servers.
wget = recursive download tool (mirror sites). curl = scriptable HTTP client (call APIs, build requests). They overlap on single-file download but the goals differ.
⚠ Common pitfall: wget retries by default, curl does not. wget follows redirects by default, curl does not. The flags differ enough that scripts are not portable between them.
Examples
wget -r -np https://example.com/docs/ # mirror
curl -L -O https://example.com/file.zip # single file
single vs double quotes around JSON bodies
In bash, single quotes keep $ and " literal, which is what JSON needs. Double quotes let the shell expand $vars and eat your quotes.
⚠ Common pitfall: Wrap JSON in single quotes: -d '{"k":"v"}'. If you need a shell variable inside, close-and-reopen: -d '{"id":"'"$ID"'"}'.
Examples
# wrong (shell eats the quotes):
curl -d "{\"k\":\"v\"}" https://api.example.com
curl could not verify the server cert against its CA bundle — usually a self-signed cert, an expired cert, or a missing intermediate.
⚠ Common pitfall: Do NOT reflexively reach for -k. Diagnose first: `openssl s_client -connect host:443 -showcerts`. Fix the chain or trust the real CA with --cacert.
The server accepted the TCP connection but closed it without sending any HTTP response — often a crash, a protocol mismatch, or hitting an HTTPS port with http://.
⚠ Common pitfall: Check you used the right scheme: hitting an HTTPS-only port with http:// (or vice versa) gives exactly this. Try the other scheme + -v.
Examples
curl -v https://example.com:443/ # try https if http gave (52)
curl -v http://localhost:8080/ # try http if it is not TLS
-w timing on curl 7.x vs newer for time_appconnect
time_appconnect (the TLS handshake timer) is 0 for plain-HTTP requests. People misread that 0 as "TLS is instant" — it just means no TLS happened.
⚠ Common pitfall: Only HTTPS URLs populate time_appconnect. If you expected TLS but see 0, you are probably hitting http:// by mistake.
Piping a remote script straight into a shell runs whatever the server returns at that instant, with your privileges. A compromised or MITM'd endpoint owns you.
⚠ Common pitfall: Download to a file first, read it, verify a published checksum / signature, THEN run. Never pipe untrusted URLs into sh.
Examples
# safer:
curl -fsSL https://example.com/install.sh -o install.sh
sha256sum -c install.sha256
less install.sh && sh install.sh
-O saves redirect target name "latest" (use -OJ -L)
With -O on a redirecting URL ending in /latest, curl names the file "latest" because it derives the name from the requested URL, not the final one.
⚠ Common pitfall: Add -L to follow the redirect and -J to honor Content-Disposition. `-OJL` gives you the real filename the server intends.
multiple -d flags get joined with & (not overwritten)
Passing -d twice does NOT replace the body — curl joins them with an &, building one combined form body. Surprising if you expected the last to win.
⚠ Common pitfall: This is a feature for building forms: `-d a=1 -d b=2` sends `a=1&b=2`. To send raw JSON twice you almost never want this — use one -d / --json @file.
-L re-sends the body on redirect (and may double-charge POSTs)
On a 307/308 redirect, -L replays your POST body to the new URL. For non-idempotent endpoints (payments, "create") this can fire the action twice.
⚠ Common pitfall: Know your endpoint's redirect codes. Inspect first with -I, and prefer idempotency keys for create/payment APIs before blindly adding -L.
Examples
curl -I -X POST https://api.example.com/pay # check for 307/308 first
What this tool does
Searchable curl cheat sheet with 80+ flags and the copy-ready
one-liners you type when calling an API from the terminal.
Fourteen categories: basic (-X / -i / -I / -v / -s / -o / -O
/ --output-dir), HTTP method (GET / POST / PUT / DELETE / PATCH
/ HEAD / OPTIONS), request body (-d, --data-raw, --data-binary
@file, --data-urlencode, -F multipart, --form-string), headers
(-H, -A user-agent, -e referer, --compressed, X-Forwarded-For),
auth (Basic -u, Bearer/JWT, --digest, --ntlm, --negotiate,
--anyauth, --aws-sigv4 for S3/DynamoDB without the SDK),
cookies (-b, -c, --cookie-jar, full browser-style session with
-b + -c together), redirects (-L, --max-redirs,
--location-trusted safety), timeout & retry (--connect-timeout,
--max-time, --retry, --retry-all-errors, --keepalive-time),
proxy (-x, --proxy-user, --socks5, --socks5-hostname for
DNS-leak safety, --noproxy), SSL/TLS (-k danger, --cacert,
--cert + --key mTLS, --tlsv1.3, --resolve to pin hostname → IP,
--cert-status OCSP), download (-OJ, range -r, resume -C -,
--limit-rate, --parallel, URL globbing [1-100], conditional -z),
upload (-T, --upload-file, multipart -F @, FTP/SFTP, upload
from stdin), debug (--trace, --trace-ascii, -w '%{http_code}\\n'
with time_namelookup / connect / appconnect / starttransfer /
total, --http2, --http3, --next, --config). Plus a "common
pitfalls" section covering eleven traps that actually waste
developer days: `-X POST` without `-d` sends empty body, the
`@` magic in `-d` that can leak local files, the myth that `-d`
URL-encodes for you (use --data-urlencode), forgetting -L so
you print a redirect stub, `-s` hiding real errors (pair with
-S), `-k` disabling TLS, error codes 6 / 7 / 28 / 35 with the
actual fix, when to reach for wget. Every entry has bilingual
EN/ZH descriptions, the trap people hit, and one to four
copy-ready examples. Search filters across command, description,
pitfall and example at once; category chips scope the list;
one-click copy. Fully client-side.
Tool details
Input
Files + Text + Structured content
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
No account required
Open the page and use it; whether results survive refresh depends on the tool.
Performance budget
Initial JS <= 25 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.
How to use
1
1. Input
Paste or drop your content into the tool panel.
2
2. Process
Click the button. All processing is local in your browser.
3
3. Copy / Download
Copy the result or download to disk in one click.
How curl Cheatsheet fits into your work
Use it before upload, handoff, archive, support review, or any moment where a file needs one local check before it leaves your machine.
File jobs
Checking file type, size, metadata, and obvious mismatch signals before sharing.
Preparing mixed folders for upload, archive, intake, or review.
Keeping sensitive files in the browser instead of sending them to an account-based service.
File checks
Do not treat the extension alone as proof of the real file type.
Review metadata before a file goes to customers, vendors, or a public page.
Keep the original file until the copied, converted, or exported result is verified.
Good next steps
These links move the current task into a more complete workflow.
A staging API returns 400 and you need the exact request that works
A POST to /orders kept 400ing in CI. You paste the failing curl
here, spot that `-X POST` had no `-d` so the body was empty, add
`-H "Content-Type: application/json" -d @order.json`, and the
server takes it. Five minutes instead of an afternoon of guessing
whether it was the gateway, the auth, or the payload.
Timing where the 3-second page latency actually lives
Ops says an internal endpoint is slow but the app logs look fine.
You grab the `-w` timing one-liner, run it against the host, and
see time_namelookup at 1.8s while connect and starttransfer are
tiny. The bottleneck is DNS, not the server. You point curl at a
faster resolver, confirm 40ms, and file the ticket against DNS.
Reproducing an S3 call without installing the AWS SDK
On a locked-down jump host with no pip and no aws-cli, you still
need to verify a bucket policy. You copy the `--aws-sigv4`
example, fill in your region and access key from env vars, and
GET the object directly. One curl line replaces a whole SDK
install you were never going to be allowed to do anyway.
Onboarding a junior who keeps shipping `-k` to production
A new teammate disables TLS verification with `-k` to silence a
cert error, then commits it. You send them the SSL/TLS section:
the pitfall line explains `-k` turns off the check entirely, and
the fix shows `--cacert ./internal-ca.pem` to trust the real
corporate CA. The cert error goes away without opening a hole.
Common pitfalls
Writing `-X POST` with no `-d` and wondering why the server 400s on an empty body; drop `-X` and just use `-d` (or `-d @file.json`), which implies POST.
Assuming `-d` URL-encodes for you, so spaces and `&` corrupt the value; use `--data-urlencode "q=hello world"` for anything with special characters.
Reaching for `-k` to kill a cert error and shipping it; that disables all TLS verification, use `--cacert ./ca.pem` to trust the right CA instead.
Privacy
This cheat sheet runs entirely in your browser. The search box filters
an in-memory array of curl commands, so your queries never leave the
tab and nothing goes into the URL. The example commands shown are
static templates with placeholder hosts and tokens; you copy them and
run them in your own terminal, so no real endpoint, token, or payload
ever touches this page. Safe to use behind a corporate proxy or on an
air-gapped host.
FAQ
Related tools
Hand-picked utilities that pair well with this one.