cURL by Example: File Upload
Upload files to a server. This example shows `-F` with file paths.
Code
# Upload a single file
curl -F "[email protected]" https://api.example.com/upload
# Upload file with custom filename
curl -F "[email protected];filename=me.jpg" https://api.example.com/upload
# Upload multiple files
curl -F "images[][email protected]" \
-F "images[][email protected]" \
https://api.example.com/upload
# Upload file + metadata fields
curl -F "[email protected]" \
-F "username=jdoe" \
https://api.example.com/registerExplanation
File uploads via HTTP use the multipart/form-data content type, and cURL makes this straightforward with the -F flag (or --form) combined with the @ symbol before the filename. The @ symbol is a special indicator that tells cURL to read the content from the specified file rather than treating the value as literal text. The syntax is field_name=@path/to/file, where field_name is the form field name that the server expects, and the path is relative or absolute to your local file. cURL reads the file content and includes it as a distinct part in the multipart request, automatically setting appropriate headers including Content-Disposition with the filename.
You have fine-grained control over how the file appears to the server. By appending ;filename=newname.ext after the file path, you can explicitly set the filename that the server will see in the Content-Disposition header, without actually renaming your local file. This is particularly useful for anonymizing uploads, testing server behavior with specific filenames, or when your local file has a different name than what the server expects. You can also specify the MIME type explicitly using ;type=mime/type (e.g., -F "[email protected];type=image/jpeg"), though cURL usually guesses this correctly based on the file extension.
One of the powerful features of multipart requests is the ability to mix file fields and regular text fields in a single request. This mirrors how HTML forms work in browsers. For example, a user registration form might include a profile picture upload (file) along with username, email, and other text fields—all sent in one request. You achieve this by using multiple -F flags: some with the @ symbol for files (-F "[email protected]") and some without for text fields (-F "username=jdoe"). This is extremely common in modern web applications and APIs. You can even upload multiple files to the same field name using array notation (-F "images[][email protected]" -F "images[][email protected]"), which many backend frameworks understand as an array of uploaded files.
Code Breakdown
@photo.jpg instructs cURL to read the file content.;filename=... overrides the filename sent in the Content-Disposition header.
