Skip to content
Latchkey

curl -d / --data: Send a Request Body

-d posts data, but it strips newlines and treats @ as a filename unless you know the variants.

Posting a body is the most common write operation in CI. The -d family has important differences you should pick deliberately.

What it does

-d / --data sends the given data as the request body and sets the method to POST with Content-Type application/x-www-form-urlencoded. Plain -d strips newlines and carriage returns and treats a leading @ as a filename to read. --data-raw sends the data literally including any @. --data-binary sends bytes exactly as given, preserving newlines, which matters for JSON files.

Common usage

Terminal
curl -d 'name=ci&state=on' https://api.example.com/x
curl -d @payload.json -H 'Content-Type: application/json' https://api.example.com/x
curl --data-raw '@literal-not-a-file' https://api.example.com/x
curl --data-binary @body.json -H 'Content-Type: application/json' https://api.example.com/x

Flags

FlagWhat it does
-d / --dataPOST body, url-encoded type, strips newlines, @ = file
--data-rawLike -d but @ is literal, not a filename
--data-binarySend bytes exactly, preserve newlines (use for files)
--data-urlencodeURL-encode the value before sending
--json <data>Shortcut that also sets JSON headers (curl 7.82+)

In CI

For posting a JSON file, prefer --data-binary @file.json so newlines are preserved exactly; plain -d @file.json collapses them, which usually is fine for JSON but can break signature checks. Always set Content-Type: application/json yourself, since -d defaults to form encoding.

Common errors in CI

Warning: Couldn't read data from file "payload.json" means the @ path is wrong or the file is missing in the runner workspace. A 400 with "unexpected token" usually means the body was form-encoded; set -H 'Content-Type: application/json' or use --json.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →