POST, PUT and forms: -d, -X, -F

curl · Essentials · 10 min

Creating and updating resources means sending request bodies, and getting encoding right avoids subtle bugs.

-d (or --data) sends a request body and switches the method to POST, with Content-Type: application/x-www-form-urlencoded:

curl -d 'name=Ann&age=30' https://example.com/users

Body variants:

  • -d @file reads the body from a file, but strips newlines. Use --data-binary @file to send a file byte for byte.
  • --data-urlencode 'q=a b&c' URL-encodes the value for you (sends q=a+b%26c), safer for user input.
  • Multiple -d options are joined with &.

-F builds a multipart/form-data body, like an HTML form with a file input: -F 'title=Report' -F 'file=@report.pdf'. Add ;type=application/pdf to set a part's content type.

-X sets the method name: -X PUT -d ..., -X DELETE, -X PATCH -d .... It changes only the word in the request line; the body still comes from -d. You do not need -X POST with -d (it is already POST), and -X with -L keeps that method on every redirect, which is often wrong. Never use -X HEAD; use -I.

-G turns -d data into a query string on a GET, convenient for search APIs: curl -G --data-urlencode 'q=rust lang' https://api.example.com/search.

Example

curl -d 'name=Ann&age=30' https://api.example.com/form
# body: name=Ann&age=30   Content-Type: application/x-www-form-urlencoded
curl --data-urlencode 'q=a b&c' https://api.example.com/s
# body: q=a+b%26c
curl --data-binary @payload.xml -H 'Content-Type: application/xml' https://api.example.com/import
curl -F 'title=Q3 report' -F 'file=@report.pdf;type=application/pdf' https://api.example.com/upload
curl -X PUT -d 'status=done' https://api.example.com/tasks/7
curl -X DELETE https://api.example.com/tasks/7
curl -G --data-urlencode 'q=rust lang' https://api.example.com/search   # GET ?q=rust+lang

Remember

  • -d sends form-encoded POST; --data-binary @file preserves bytes
  • -F makes multipart uploads; @file attaches a file
  • -X only renames the method; -G moves -d data into the query string

Watch out for

  • Sending a JSON file with -d @file.json: newlines are stripped and the Content-Type is wrong.

Check yourself

  1. What is sent by `curl -X PUT -d 'a=1' URL`?
  2. Which option uploads a file as an HTML-form-style multipart request?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: curl.se/docs/manpage.html#-d