Curl POST Body Example

The body of a POST can come from four places: the command line, a file, another program's output, or a block of text in your script. Where it comes from decides how faithfully it arrives.

Last updated . How this page is checked.

The command

curl https://httpbin.org/post \
  -H "Content-Type: text/plain" \
  -d "Body text, sent exactly as written."

Opens the request console with this request filled in. It is sent from api-tester.com's server rather than from your machine, so it shows what the endpoint returns, not how your own network or curl build behaves.

What the flags do

FlagWhat it does
-d "text"The body, given inline.
--data-binary @fileThe body, read from a file and left unchanged.
--data-binary @-The body, read from standard input.
-H "Content-Type: ..."What the body is. Curl says "form" unless told otherwise.
--trace-ascii -Print the request as sent, body included.

A file, a pipe or a here-document

Inline text suits a short body. Anything longer is easier to get right from a file, since no shell quoting is involved at all. A dash in place of the filename reads standard input, which connects curl to whatever produced the data. A here-document does the same with text kept in the script; quoting the marker, as in <<'EOF', stops the shell from expanding dollar signs inside the block.

curl --data-binary @payload.txt -H "Content-Type: text/plain" https://httpbin.org/post

generate-report | curl --data-binary @- -H "Content-Type: text/csv" https://httpbin.org/post

curl --data-binary @- -H "Content-Type: application/json" https://httpbin.org/post <<'EOF'
{
  "name": "Ada",
  "notes": "a long body stays readable here"
}
EOF

Confirming what was sent

Verbose mode shows request headers and stops there; the body is not printed. --trace-ascii prints everything, with the body under a "Send data" line and its size in bytes, which settles most arguments about a missing character or an extra newline. The other approach is an echo endpoint: httpbin returns the body it received, under form if it parsed as form fields, json if it parsed as JSON, and data otherwise.

curl -s -o /dev/null --trace-ascii - -d "name=Ada&role=admin" https://httpbin.org/post \
  | grep -A 2 "Send data"

Length, buffering and big bodies

Curl announces the body's size in Content-Length whenever it knows it, and for -d and --data-binary it always does, because it reads the entire input into memory before connecting, standard input included. That is fine for kilobytes and wasteful for gigabytes. To stream instead, use -T - with -X POST: curl forwards data as it arrives, using chunked transfer on HTTP/1.1 since the total is unknown.

tar czf - ./logs | curl -X POST -T - \
  -H "Content-Type: application/gzip" https://uploads.example.com/logs

Common mistakes

  • Double quotes let the shell edit the body. Dollar signs and exclamation marks are interpreted before curl runs; single quotes or a file avoid that.
  • A trailing newline counts. echo appends one to piped input. Use printf when the receiver checks a signature or an exact length.
  • A body on a GET is legal to send and widely ignored. Combine -X GET with -d only for an API that explicitly asks for it.

Related curl examples

More under Request bodies

References

These links leave api-tester.com, which is independent of the projects they point to.

FAQ

How do I send a body in a curl POST request?

Pass it with -d for inline text or --data-binary @file for a file, and set a Content-Type header that describes it. Curl switches to POST when a body is present.

How do I send a raw text body with curl?

Use --data-binary with the text or @file and add -H "Content-Type: text/plain". --data-binary sends the bytes unchanged.

How can I see the request body curl sent?

Add --trace-ascii - to print the full request including the body, or post to an echo service such as httpbin.org/post and read what it received.