curl is a project providing a library and command-line tool for transferring data using various protocols.
The command line tool can be used inside shell scripts with ease and it has around 120 command line options for various tasks.

Is a really useful tool, in both application debug and web penetration testing activities.

Today i'd like to share my own cheatsheet, built during day by day activities.

GET Requests

These curl recipes show you how to send GET requests with curl.
The GET method is the default method for making requests in curl so you
don't have to specify any arguments.

Send a GET Request and Print the Response to Screen

$ curl

You don't need to specify any arguments to make a GET request: the command makes a GET request to and prints the returned content to screen.

Send a GET Request and Save the Response to a File

$ curl -o response.txt

With this command, curl makes a GET request to and saves the body of the HTTP response to response.txt file.

POST requests

By default, curl sends GET requests: to make it send POST requests, use the -X POST command line argument and use the -d argument to add POST data to the request.
To change the Content-Type header that tells the web server what type of data you're sending, use the -H argument.

Send an Empty POST Request

curl -X POST

This recipe uses the -X POST option that makes curl send a POST request to Once it receives a response from the server, it prints the response body to the screen. It doesn't send any POST data.

Send a POST request with form data

curl -d 'login=emma&password=123' -X POST

This recipe sends a POST request to with login=emma&password=123 data in request's body. When using the -d argument, curl also sets the Content-Type header to application/x-www-form-urlencoded. Additionally, when the -d option is set, the -X POST argument can be skipped as curl will automatically set the request's type to POST.

Send a POST request and follow a redirect

curl -L -d 'tweet=hi'

By default, curl doesn't follow the redirects .
The -L command line option tells curl to follow any possible redirects that it may encounter in the way. (the-d argument forces curl to make a POST request)

Send a POST request with JSON data

curl -d '{"login": "andrea", "password": "verystrongpassword"}' -H 'Content-Type: application/json'

This request can be accomplished passing JSON to the -d option and also using the -H option that sets the Content-Type header to application/json (necessary because otherwise, the web server won't know what type of data this is).

Send a POST Request with XML Data

curl -d '<user><login>andrea</login><password>verystrongpassword</password></user>' -H 'Content-Type: text/xml'

Just like the form data and JSON data, XML data is specified in the -d argument, and the Content-Type header is changed to text/xml via the -H argument.

Send a POST request with plain text data

curl -d 'hello, world!' -H 'Content-Type: text/plain'

Just sends a POST request with a plain text string hello, world! in request's body. The Content-Type header is filled with text/plain to tell web server that it's just plain text coming in.

Send a POST Request with Data from a File

curl -d '@data.txt'

The POST data are loaded from a file called data.txt.
The extra @ symbol before the filename tells curl that data.txt is a file and not just a string.

URL-encode POST Data

curl --data-urlencode 'comment=hello, world!'

The -d argument assumes that data are already URL-encoded.
If it is not, just replace -d with --data-urlencode: it works exactly the same way as -d, except the data gets URL-encoded by curl before the request.

POST a binary file

curl -F 'file=@photo.png'

The -F argument forces curl to make a multipart form data POST request and also sets the Content-Type header to multipart/form-data.

POST a binary file and set its MIME type

curl -F 'file=@photo.png;type=image/png'

Similar to the previous example, the -F argument is used to upload a binary file via a multipart POST request, but now is also specified the MIME type of this file as image/png.
If no type is specified, then curl sets it to application/octet-stream.

POST a binary file and change its filename

curl -F 'file=@photo.png;filename=selfie.png'

This example uses the -F argument to upload a photo.png via a POST request and set the filename sent to the web server to selfie.png.

HTTP Headers manipulation

Add a single header

curl -H 'Accept-Language: en-US'

The -H argument is used to add Accept-Language: en-US header to a GET request to this header tells site to serve the English version of the page.

Add two or more headers

curl -H 'Accept-Language: en-US' -H 'Other header: xyz' -H 'Final header: zzz'

Using multiple -H argoments is possible to send multiple headers to the request.

Add an empty header

curl -H 'Nothing;'

If you pass Nothing; (or other text, with a semicolon at the end) as an argument to the -H option, curl converts it to an empty header Nothing: with no value.

User Agent manipulation

Change the User Agent to Firefox

curl -A 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0'

The -A argument is used sets the user agent to Firefox 60 (Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0).

Change the User Agent to Chrome

curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'

Similar to the previous example.

Change the User Agent to Google Bot

curl -A 'Googlebot/2.1 (+'

Really useful to skip paywalls: often, websites will serve the content to a Google bot (so that they are indexed) but when a real browser requests them, they'll show a paywall.

Remove the User Agent

curl -A ''

The empty string passed to the -A command line option tells curl to remove the user agent header and not to send User-Agent HTTP header.

Working with cookies

curl -b 'session=xyz'

The -b name=value argument sets a cookie with the name session to the value xyz in a GET request to

Add two or more cookies

curl -b 'session=xyz' -b 'logged=1'

The same syntax of previous example can be used to set two o more cookies.

curl -b 'session='

Using only the first half of -b name=value option, curl can send an empty cookie that in the HTTP header looks like this Cookie: session=.

Save cookies to a file

curl -c cookies.txt

The -c cookies.txt option saves the response cookies to cookies.txt file. When curl makes a GET request to, the web server responds with one or more Set-Cookie: name=value header values.
Curl takes them and saves them to a file.

Load cookies from a file

curl -b cookies.txt

The cookies saved in the previous example can be loaded with the -b cookies.txt option.

Referrer manipulation

Add a referrer

curl -e ''

This -e argument is used to set the HTTP referrer to and makes a GET request to In the access.log file of's webserver, it will appear that someone came from Google while searching for devops.

Send an empty referrer

curl -e ''

Using the -e option leaving the argument empty '' clears the value part of Referer: HTTP header and sends an empty HTTP referer.

Use the Basic HTTP authentication

Set the username and password via the -u argument

curl -u 'andrea:strongpassword'

This example uses the -u 'andrea:strongpassword' argument to set the username to andreaand password to strongpassword.
The username and password is then base64-encoded by curl and sent to the server at in the Authorization HTTP header.

Set the username and password in the URL


If you put the username and password in the URL , curl is smart enough to figure it out and it does exactly the same as in the previous example, performing a basic HTTP authentication.

Make curl prompt for the password

curl -u 'andrea'

If you skip the password part, curl will asks for the password on the command line.
This is useful if you don't want the password to be saved in the shell history.

Working with proxies

Use socks proxies

We can use the -x argument to set the proxy protocol, for examplesocks5:

curl -x socks5://

In this example, the proxy username is set to andrea, proxy password to strongpassword, proxy hostname to, and proxy port to 8080. After connecting to the proxy, curl then makes a GET request to
The same syntax can be used for socks4 proxies:

curl -x socks4://

Use an HTTP proxy

curl -x

If you avoid to specify the protocol:// part of the proxy address, curl will assumes that an HTTP proxy is used.

Debugging requests

Set verbosity

curl -v

The -v argument asks curl to print detailed information about the request and the response.
Lines prefixed by > is the data sent to the server, lines prefixed by < is the data received from the server, and lines starting with * is misc information, such as connection information, SSL handshake information, and protocol information.

Detailed trace

curl --trace -

The --trace - argument enables a full trace hexdump of all incoming and outgoing data.
Adding --trace-time argument to the previous example makes curl add timestamps to full trace output

curl --trace - --trace-time

Print only specific debug messages

curl -i

By default, curl prints the response body to the screen: adding the -i argument makes it also print response headers.
If you need, you can also print only the response headers:

curl -s -o /dev/null -D -

The -s argument makes curl silent and hides errors and progress bar, then -o /dev/null makes curl ignore the response body, and -D - prints response headers to stdout.
Further, you can also print only the request headers:

curl -v -s -o /dev/null --stderr - | grep '^>'

A little more tricky: the -v argument enables the verbose output, the -s argument makes curl silent, then the -o /dev/null argument makes curl ignore the output from the server , the --stderr - argument redirects stderr to stdout , and finally print all lines that begin with > (that contain request headers) using grep.
And finally, you can print only the response code:

curl -w '%{response_code}' -s -o /dev/null

The -w argument makes curl print the extra information %{response_code} ( the response code of the request ) after the request has completed.
To make curl only print the code and not the content or other information, we also use -s to silence curl and -o /dev/null that ignores the response output.