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
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/xFlags
| Flag | What it does |
|---|---|
| -d / --data | POST body, url-encoded type, strips newlines, @ = file |
| --data-raw | Like -d but @ is literal, not a filename |
| --data-binary | Send bytes exactly, preserve newlines (use for files) |
| --data-urlencode | URL-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.