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: curl -X POST [options] [URL].
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 \
https://example.com/posts
Three options provided here are:
- -X was used to provide the HTTP method we use to send the request. In this case, the method is POST
- -d was used to provide the associated data in the body of the HTTP request
- -H was used to specify headers for the request
Each of these options also have associated aliases. For example, for -X you can instead provide --request, and for -H you can provide --headers.
These are just some of the possible options, but there are many others, enumerated below.
Common POST Request Operations
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 \
https://example.com/posts
## Image Upload
curl -H "Content-type: multipart/form-data" \
-F [email protected] \
https://example.com/avatar.cgi
# 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 \
https://example.com/posts
As we can see from the image, to use multipart/form-data content-type, we send data with the -F (or --form option). To use application/x-www-form-urlencoded content-type, we use the -d (or --data) 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
To send image data in a POST request, include the image in the form data by prefixing the filename with an @ symbol as follows:
curl -F [email protected] \
https://example.com/avatar.cgi
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 \
https://example.com/avatar.cgi
Common Gotchas
- Argument names are case sensitive. For example, -F corresponds to the argument for form data, while -f 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. -d "{ "title":"foo" }" would be invalid
- You can only use breaklines if you include \ a backslash character. There can be no trailing spaces after the backslash
cURL POST Request Arguments
Arguments available for the options field of the curl POST format (curl -X POST [options] [URL]) 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.
Written by
Zev Stravitz
Software Engineer II, Rutter
Filed Under
Related Articles
Bash If Statement
Learn how to use the if statement in Bash to compare multiple values and expressions.
Bash While Loop
Learn how to use and control the while loop in Bash to repeat instructions, and read from the standard input, files, arrays, and more.
POST JSON Data With Curl
How to send valid HTTP POST requests with JSON data payloads using the curl command and how to avoid common syntax pitfalls. Also, how to solve the HTTP 405 error code.
Use Cookies With cURL
Learn how to store and send cookies using files, hard-coded values, environment variables with cURL.
Loop Through Files in Directory in Bash
Learn how to iterate over files in a directory linearly and recursively using Bash and Python.
How To Use sudo su
A quick overview of using sudo su
Generate, Sign, and View a CSR With OpenSSL
Learn how to generate, self-sign, and verify certificate signing requests with `openssl`.
How to use sudo rm -rf safely
We'll help you understand its components
How to run chmod recursively
Using -R is probably not what you want
Run Bash Shell In Docker
Start an interactive shell in Docker container
Reading User Input
Via command line arguments and prompting users for input
Bash Aliases
Create an alias for common commands