curl Cheatsheet

Headers and Methods

Use this curl reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Setting the method

-X / --request overrides the method curl would otherwise pick. It only changes the verb, it never adds a body, so -X POST on its own sends a POST with Content-Length: 0.

curl -X DELETE https://api.example.com/users/42
curl -X PUT -d '{}' -H 'Content-Type: application/json' https://ex.com/v1/a
curl -X POST https://api.example.com/ping        # empty POST body

Most of the time you do not need -X. The body flags already imply the method, and forcing the verb is what breaks redirect following.

You passcurl sends
nothingGET
-d, --data-raw, --data-binary, --data-urlencodePOST
--jsonPOST
-F / --formPOST (multipart)
-T / --upload-filePUT (HTTP)
-I / --headHEAD
-G / --getGET, data moved to the query string

Combining -X POST with -L keeps POST on every hop, because -X is sticky. Without -X, curl correctly downgrades a 301/302/303 redirect to GET. If you want the method preserved deliberately, that is --post301, --post302, and --post303.

Request headers

-H / --header is repeatable and takes a full Name: value string. curl sets Host, User-Agent, and Accept: */* by default, and any -H with the same name replaces the default rather than adding a second copy.

curl -H 'Accept: application/json' \
     -H 'X-Request-Id: 7f3a' \
     -H 'Authorization: Bearer eyJhbGci...' \
     https://api.example.com/me
FormEffect
-H 'Name: value'Set or replace the header
-H 'Name;'Send Name with an empty value
-H 'Name:'Remove an internal header curl would send
-H @headerfileRead one header per line from a file
-A 'ua'Shorthand for User-Agent
-e 'url'Shorthand for Referer
--proxy-headerHeader for the proxy only, not the origin
curl -H 'Accept:' https://ex.com/          # drop the default Accept
curl -H 'Host: internal.svc' https://10.0.0.4/health

Header casing and duplicates

HTTP/1.1 header names are case insensitive, but HTTP/2 and HTTP/3 require lowercase on the wire. curl lowercases for you on those versions, so the casing you type only matters for readability. Duplicate -H entries with the same name are both sent, which servers often reject, so prefer one line per header.

curl -v --http1.1 -H 'X-A: 1' -H 'X-A: 2' https://ex.com/ 2>&1 | grep '^> X-A'

Reading response headers

FlagBehavior
-i / --includeResponse headers then the body, on stdout
-I / --headHEAD request, headers only
-D <f> / --dump-header <f>Write headers to a file, - means stdout
-v / --verboseRequest and response headers on stderr
-w '%header{name}'Print one response header value
curl -sI https://example.com | grep -i '^content-type'
curl -s -D - -o /dev/null https://example.com
curl -so /dev/null -w '%header{content-type}\n' https://example.com

%header{...} needs curl 7.84.0 or newer and is the clean way to pull a single value without piping through grep.

Conditional and range requests

Cheap ways to ask for less than the whole body, useful against big files and CDN-cached assets.

curl -r 0-1023 -o head.bin https://ex.com/big.iso     # first 1 KiB
curl -r -500   -o tail.bin https://ex.com/big.iso     # last 500 bytes
curl -z 'Tue, 01 Apr 2025 00:00:00 GMT' -O https://ex.com/f.txt
curl -z file.txt -O https://ex.com/file.txt           # if newer than local
curl --etag-save et.txt -O https://ex.com/f.json      # store the ETag
curl --etag-compare et.txt -O https://ex.com/f.json   # send If-None-Match

-r / --range sends Range, and -z / --time-cond sends If-Modified-Since. A server that ignores Range answers 200 with the whole body instead of 206, so check the status before trusting the size.

HTTP version selection

curl negotiates the highest version both sides support. Pin it when you are isolating a protocol bug.

FlagMeaning
--http1.1Force HTTP/1.1
--http2ALPN upgrade to HTTP/2 over TLS
--http2-prior-knowledgeHTTP/2 over cleartext, no upgrade dance
--http3HTTP/3 over QUIC
--http3-onlyHTTP/3 with no fallback
--no-alpnDisable ALPN, forcing HTTP/1.1 in practice
curl -sI --http1.1 https://example.com | head -1
curl -so /dev/null -w '%{http_version}\n' https://example.com

--http3 requires a build with an HTTP/3 backend. Check curl -V for HTTP3 in the feature line first, since a curl without it fails the option rather than falling back.