This is a hack, but it works. UploadFile[url_, filePath_, urlParams___] := With[ { bytes = Import[filePath, "Byte"], filename = StringJoin[FileBaseName[filePath], ".", FileExtension[filePath]] }, URLExecute[ url, urlParams, "Method" -> "POST", "MultipartElements" -> { {"file\"; filename=\"" <> filename, "application/octet-stream", bytes} }, "Headers" -> { "Accept" -> "application/json; charset=UTF-8", "Content-Type" -> "multipart/form-data" } ] ] Notice that I'm stuffing the `filename` parameter in the first element of `"MultipartElements"` along with the field name in order to get it in `Content-Disposition` for that element. (* Get a new ephemeral RequestBin from http://requestb.in/, then put URL below: *) UploadFile["http://requestb.in/1hyjbdl1", "ExampleData/rose.gif"] result: Content-Disposition: form-data; name="file"; filename="rose.gif" Theoretically you could also specify `"Content-Disposition" -> "form-data; filename=\"foo\""` in the request header, but the server would have to be expecting exactly one file in the form-data and parse accordingly, whereas the above approach with filenames in each part I think is more commonly expected. --- **Edit** In version 11, there's a no-hack way to do this: image = FindFile["ExampleData/Ocelot.jpg"]; req = HTTPRequest[url, <|"Body" -> {"image" -> File[image]}|>]; URLRead[req, "Body"] [Docs](https://reference.wolfram.com/language/ref/URLRead.html) (see Scope > "To send files...") **Edit 2** This evidently uses `expect: "100-continue"`, which is not supported by some common load balancers that may be between you and your server. Thus, it may not work in many cases.