The command
curl -F "file=@report.pdf" https://httpbin.org/post
What the flags do
| Flag | What it does |
|---|---|
-F field=@path | Multipart upload. field must be the name the server expects. |
-F "field=@path;type=mime" | Override the media type curl guessed from the extension. |
-F "field=@path;filename=name" | Send a different filename from the one on disk. |
--data-binary @path | The file is the entire request body, unmodified. |
-T path | Stream the file with PUT. |
Multipart: a file inside a form
This is what a browser sends from a file input, and what most upload endpoints expect. The part name before the = is not decoration; if the server looks for avatar and you send file, it reports that no file was uploaded. Other form fields ride along as extra -F flags.
curl https://httpbin.org/post \
-F "avatar=@photo.png;type=image/png;filename=ada.png" \
-F "caption=Portrait, 1843"
# several files under one field name
curl -F "docs=@a.pdf" -F "docs=@b.pdf" https://httpbin.org/post
Raw: the file is the body
Object stores and many JSON APIs want the file as the whole body, with no form wrapper. Use --data-binary, which sends the bytes untouched, and state the media type, because curl would otherwise label it as form data. Plain -d @file is wrong here: it strips carriage returns and newlines, which corrupts any binary file and reflows any text file.
For large files prefer -T, which streams from disk instead of reading the file into memory first. It sends PUT; add -X POST if the endpoint insists on POST.
curl --data-binary @photo.png \
-H "Content-Type: image/png" https://httpbin.org/post
curl -T video.mp4 -H "Content-Type: video/mp4" https://uploads.example.com/video.mp4
Common mistakes
- Do not set
Content-Type: multipart/form-datayourself. It removes the boundary curl would have added and the upload becomes unparseable. - A
413is the server's or proxy's size limit, not a curl problem. - Paths with spaces or commas need quoting inside the flag:
-F 'file=@"my report.pdf"'.
Related curl examples
Curl POST Form Example
HTML forms post in one of two encodings, and curl has a flag for each.
Curl PUT Example
PUT replaces the resource at a URL with the body you send.
Curl Download File Example
Curl prints what it downloads to the terminal unless told to save it.
Curl -d Flag Example
-d looks like "send this data", but it does three things at once and quietly edits file input.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under Request bodies
References
- curl man page: -F — Attaching files to a multipart body, with type and filename.
- MDN: Content-Disposition — How each part of a multipart body names its field and file.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I upload a file with curl?
Use -F "field=@path", for example curl -F "file=@report.pdf" URL. Curl sends a multipart/form-data POST with the file attached under that field name.
How do I send a file as the raw request body with curl?
Use --data-binary @path with a Content-Type header naming the file type. Unlike -d, --data-binary does not strip newlines.
How do I set the content type of an uploaded file?
Append ;type= to the form part, for example -F "file=@data.bin;type=application/octet-stream".