Send request data

Submit forms and files

Choose URL-encoded form data or multipart form data and upload a local file deliberately.

10 minute lesson

~~~

HTML-style forms commonly send data in one of two encodings. URL-encoded data packs fields into name=value pairs, the same format as a query string, sent as the request body. Multipart data splits the body into parts separated by a boundary, each with its own headers. Multipart is the normal choice when a field contains a file, because files are binary and do not survive URL encoding gracefully.

curl has one option for each: --data for URL-encoded, --form for multipart.

A simple form

For text-only fields, URL-encoded is what most login and search forms use:

curl --data 'title=Lab notes' --data 'author=mina' https://httpbin.org/post

The echo shows both fields under form, and the Content-Type header reads application/x-www-form-urlencoded.

A form with a file

Create a small file, then send one text field and one file:

echo 'first line of my notes' > notes.txt
curl --form 'title=Lab notes' --form '[email protected]' https://httpbin.org/post

The response should show a form value and file content separately:

{
  "files": {
    "attachment": "first line of my notes\n"
  },
  "form": {
    "title": "Lab notes"
  }
}

That split is your verification. title arrived as an ordinary field, and attachment arrived as a file part with its content intact. curl builds the multipart boundary and per-part headers for you — the fiddly parts of the format you never want to write by hand.

The @ prefix reads a local file and uploads it as a file part. If you want the file’s content as a plain text field instead, use < rather than @. And when the server cares about the file’s MIME type, state it: --form '[email protected];type=text/plain'.

The mistake to avoid

Check the path and destination before running a command copied from elsewhere. @ means “read this file from my disk and send it over the network” — pasted blindly, a command like --form 'config=@~/.ssh/id_ed25519' uploads your private key to whoever runs the server. curl also fails with 26 when the file does not exist, so a typo in the path shows up as a read error, not a silent empty upload.

One more trap: mixing --data and --form in the same command does not work. A request body has one content type. Pick the encoding the server expects and stick to it.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →