Curl Post Request

Last Updated 2022-10-17

cURL (curl) is an open source command-line tool used for transferring data over a network. POST is an HTTP request method which is used to send data to the server. (Read more on POST requests here.)

The format of a POST request with curl is: [.inline-code]curl -X POST [options] [URL][.inline-code].

An example POST request to submit a todo list task to a REST API might look like:

 curl -H 'Content-Type: application/json' \
      -d '{ "title":"foo","body":"bar", "id": 1}' \
      -X POST \

Three options provided here are:

  • [.inline-code]-X[.inline-code] was used to provide the HTTP method we use to send the request. In this case, the method is POST
  • [.inline-code]-d[.inline-code] was used to provide the associated data in the body of the HTTP request
  • [.inline-code]-H[.inline-code] was used to specify headers for the request

Each of these options also have associated aliases. For example, for [.inline-code]-X[.inline-code] you can instead provide [.inline-code]--request[.inline-code], and for [.inline-code]-H[.inline-code] you can provide [.inline-code]--headers[.inline-code].

These are just some of the possible options, but there are many others, enumerated below.

[#common-operations]Common POST Request Operations[#common-operations]

[#sending-form-data]Sending Form Data[#sending-form-data]

There are two common ways to send form data with POST requests, each with different content-types, demonstrated below:

# multipart/form-data
## Text Field
curl -H "Content-type: multipart/form-data" \
     -F title=foo \
     -F body=bar \
     -F id="1" \
     -X POST \

## Image Upload
curl -H "Content-type: multipart/form-data" \
     -F profile=@avatar.jpg \

# application/x-www-form-urlencoded
curl -H "Content-type: application/x-www-form-urlencoded" \
     -d "title=foo" \
     -d "body=bar" \
     -d "id=1" \
     -X POST \

As we can see from the image, to use multipart/form-data content-type, we send data with the [.inline-code]-F[.inline-code] (or [.inline-code]--form[.inline-code] option). To use application/x-www-form-urlencoded content-type, we use the [.inline-code]-d[.inline-code] (or [.inline-code]--data[.inline-code]) option.

Generally speaking, multipart/form-data is more often used to send binary data like images, while application/x-www-form-urlencoded is used to send text data.

By default, HTML forms will send data using the content-type of application/x-www-form-urlencoded when submitted.

[#sending-image-data]Sending Image Data[#sending-image-data]

To send image data in a POST request, include the image in the form data by prefixing the filename with an [.inline-code]@[.inline-code] symbol as follows:

 curl -F profile=@avatar.jpg \

The @ symbol forces the content part of the form to be a file, which is then uploaded to the server.

Alternatively, we could base64 encode the image and send it as a field in a form field or JSON body field of your request, but this is far less ergonomic:

 curl -H 'Content-Type: application/json' \
     -d  '{"image" : "'"$(base64 ~/avatar.jpg)"'"}' \
     -X POST \

[#common-gotchas]Common Gotchas[#common-gotchas]

  • Argument names are case sensitive. For example, [.inline-code]-F[.inline-code] corresponds to the argument for form data, while [.inline-code]-f[.inline-code] is a flag indicating whether we want to fail fast with no output
  • When passing content of type application/json, be sure to wrap the JSON body in single quotes - e.g. [.inline-code]-d "{ "title":"foo" }"[.inline-code] would be invalid
  • You can only use breaklines if you include [.inline-code]\[.inline-code] a backslash character. There can be no trailing spaces after the backslash

[#post-request-arguments]cURL POST Request Arguments[#post-request-arguments]

Arguments available for the options field of the curl POST format ([.inline-code]curl -X POST [options] [URL][.inline-code]) are enumerated below:

Short Option Long Option Argument(s) Purpose
-X --requests <method>

(use \"POST\" or POST requests)
Specify the request method to use when communicating with an HTTP server
-b --cookie <data|filename> Specify which file to write all cookies after completed operation
-c --cookie-jar <filename>
-d --data <data> Send data in POST request
-f --fail Fail fast with no output on server errors
-F --form <name=content> Form data for content-type application/x-www-form-urlencoded
-H --header <header/@file> Header to include in the request
-i --include Include HTTP headers in the output
-l --head Fetch the headers only
-k --insecure Skip verification that connection is secure
-L --location If a redirect is received (3XX), force curl to redo the request on the new address
-o --output <file> Write output to file instead of stdout
-O --remote-name Write output to a local file named like the remote file
-s --silent Do not show progress meter or error messages
-v --verbose Make curls verbose during operation. Useful for debugging
-w --write-out <format> Make curl display information on stdout after a completed transfer. See possible variables to include in output here

Read more on the official curl docs.