422

I need to make a POST request via cURL from the command line. Data for this request is located in a file. I know that via PUT this could be done with the --upload-file option.

curl host:port/post-file -H "Content-Type: text/xml" --data "contents_of_file"
3

6 Answers 6

595

You're looking for the --data-binary argument:

curl -i -X POST host:port/post-file \
  -H "Content-Type: text/xml" \
  --data-binary "@path/to/file"

In the example above, -i prints out all the headers so that you can see what's going on, and -X POST makes it explicit that this is a post. Both of these can be safely omitted without changing the behaviour on the wire. The path to the file needs to be preceded by an @ symbol, so curl knows to read from a file.

Sign up to request clarification or add additional context in comments.

9 Comments

the @ part is extremely important!
actually you can use just -d flag
@Tol182 -d will cause curl to strip newlines, but --data-binary won't.
For those that can't get it to work, make sure that you are specifying the content type in your headers!
If you're executing the curl command from the same path as your data file, its just --data-binary "@file".
|
138

I need to make a POST request via Curl from the command line. Data for this request is located in a file...

All you need to do is have the --data argument start with a @:

curl -H "Content-Type: text/xml" --data "@path_of_file" host:port/post-file-path

For example, if you have the data in a file called stuff.xml then you would do something like:

curl -H "Content-Type: text/xml" --data "@stuff.xml" host:port/post-file-path

The stuff.xml filename can be replaced with a relative or full path to the file: @../xml/stuff.xml, @/var/tmp/stuff.xml, ...

1 Comment

In case you need to send a named field, you can also use --data "name@stuff".
27

If you are using form data to upload file,in which a parameter name must be specified , you can use:

curl -X POST -i -F "parametername=@filename" -F "additional_parm=param2" host:port/xxx

Comments

9

Most of answers are perfect here, but when I landed here for my particular problem, I have to upload binary file (XLSX spread sheet) using POST method, I see one thing missing, i.e. usually its not just file you load, you may have more form data elements, like comment to file or tags to file etc as was my case. Hence, I would like to add it here as it was my use case, so that it could help others.

curl -POST -F comment=mycomment -F file_type=XLSX -F file_data=@/your/path/to/file.XLSX http://yourhost.example.com/api/example_url

Comments

6

I was having a similar issue in passing the file as a param. Using -F allowed the file to be passed as form data, but the content type of the file was application/octet-stream. My endpoint was expecting text/csv.

You are able to set the MIME type of the file with the following syntax:

-F 'file=@path/to/file;type=<MIME_TYPE>'

So the full cURL command would look like this for a CSV file:

curl -X POST -F 'file=@path/to/file.csv;type=text/csv' https://test.com

There is good documentation on this and other options here: https://catonmat.net/cookbooks/curl/make-post-request#post-form-data

Comments

2

I had to use a HTTP connection, because on HTTPS there is default file size limit.

https://techcommunity.microsoft.com/t5/IIS-Support-Blog/Solution-for-Request-Entity-Too-Large-error/ba-p/501134

curl -i -X 'POST' -F 'file=@/home/testeincremental.xlsx' 'http://example.com/upload.aspx?user=example&password=example123&type=XLSX'

1 Comment

This only applies to windows servers running IIS with the default limit in place. Outside of that, most websites these days will force HTTPs. If the server is one you control, you can just increase the file size limit if that is a viable use case for your service.