cURL tips and tricks

5 min read

cURL1 (or curl as I will refer to it for the rest of the article) is an incredible tool and a worthy asset in your developer toolkit. Like every great craftsman, you as a developer deserve great tools. Granted curl can be daunting and seemingly tough to learn at first, I promise you its worth your investment. This is a write up of basic to more advanced tips and tricks that I accumulated of the years of reading blog posts, curl man pages, StackOverflow, …

The basics 📓

Let’s start with some basic commands to get data from the server and also let’s figure out how we can send data. Feel free to execute these commands step by step while you go through the article.

First of let’s try a simple GET request.

Terminal window
curl https:/

If all goes well you should be presented with a response quite similar to this one:

"args": {},
"headers": {
"Accept": "*/*",
"Host": "",
"User-Agent": "curl/7.54.0",
"X-Amzn-Trace-Id": "Root=1-5e59668c-c7281c104fb3310fc774ed7d"
"url": ""

That was quite easy, wasn’t it? Learning curl with httpbin is quite nice because it echoes whatever you send to it right back at you. So now what if we just want to send a HEAD request:

Terminal window
curl -I

Are there any other types of requests we can send?

Terminal window
curl -d 'firstname=Takeshi&lastname=Kovacs'
curl -d 'fullname=Takeshi Kovacs' -X PUT

The -X parameter allows you to change the method. The following methods are supported:

  • GET
  • POST
  • PUT

Right now what happens if we send a request to a server and get redirected. Before running the next command try requesting with the commands you already know.

So how do we follow the redirect with curl?

Terminal window
curl -I -L

As it sounds, such a request follows the Location header to reach the endpoint.

Tip: HTTP response codes The first digit of an HTTP response defines the error group:

  • 1xx: informational
  • 2xx: success
  • 3xx: redirections
  • 4xx: client-side errors
  • 5xx: server-side errors

And oh yeah you can also customize the headers you send over via curl::

Terminal window
curl -H 'X-First-Name: Takeshi'
curl -d '{"name": "Takeshi"}' -H 'Content-Type: application/json'

Cookies 🍪

Nom nom cookies. HTTP Cookies are key/value pairs that a client stores on behalf of the server. They are sent back and forth on every request to allow clients to store state between requests. curl has a couple of ways to allow a cookie to be sent to the server. In it’s simplest form you can just use --cookie:

Terminal window
curl --cookie "SOME_COOKIE=Yes"

Get a cookie from the server and write it to a file.

Terminal window
curl -c cookie.txt

You can add -i to print the headers and do some debugging. With -L like you learned earlier you can follow the redirect. This will then print the cookies.

Terminal window
curl -i -L -c cookie.txt

You can get the current cookies back with -b.

Terminal window
curl -b cookie.txt

Tip: Cookie file format?

cURL uses a cookie format called Netscape, which each line is a single piece of information represented by following fields (read from left-to-right):

# Netscape HTTP Cookie File TRUE / FALSE 946684799 NETSCAPE_ID 100103

JSON Combo {}

Most of the time I use curl to request resources that return a JSON response. These can become long and as just plaintext hard to reason with, parse or filter. For that, we will need to create a combo with an amazing tool called jq. It’s free to install on most operating systems:

Let’s start with piping a JSON response from curl directly into jq.

Terminal window
curl | jq

Now that’s pretty neat, we get our JSON response back and thanks to some colouring form jq we can more easily digest the response. We could also try and filter the response and just select the id.

Terminal window
curl | jq '.id'

There is much more you can accomplish by combining curl and jq. jq has amazing documentation that can help you learn more about how to use it.

Uploading ⬆️

Ok, let’s look at some more advanced commands we can construct and figure out if we can upload or download a file.

  • -T Uploads the given file
  • --date @filename yes you can use the the --data or -d parameter with an @ to simply upload a file
Terminal window
curl -T uploadme https:/
curl --data '@uploadme' https:/

Sometimes you might get some data via a pipe, even in this case curl got your back:

Terminal window
cat uploadme | curl --data '@-' https:/

To download a file from a server you use -o, the next argument will be the name of the file after it is downloaded.

Terminal window
curl -o file https:/

You can also use capital o -O this will create a file named exactly like it was on the server.

But wait I got a form that gets posted and I need to fill in some data. No worries curl still got you covered.

Terminal window
curl -F 'firstname=Takeshi' -F 'lastname=Kovacs' https:/

This is an example of a multipart form post.


Basic authentication

Terminal window
curl -u admin:secret

Capital -U is used for proxy authentication

Little gems 💎

Do you support HTTP/2 or HTTP/3?

Terminal window
curl --http2
curl --http3

HTTP/3 needs to be explicitly enabled during the build process. Please refer to this upgrade guide if you want to play with it:

Another interesting gem:

Terminal window
curl --path-as-is https://example/hello/../world/

Don’t squash sequences of /../ or /./ in the given URL path.

Terminal window
curl -w 'Type:%{content_type}\nCode:%{response_code}\n' -I -L

Writes out information after transfer has completed by using a special %{variable}. 2