curl POST JSON: send a JSON body with curl
- tool
- curl
- versions
- curl 7.82+, curl 8.x
- os
- linux, macos, windows
To POST JSON with curl, pass the body with -d and set the content type yourself: curl -H 'Content-Type: application/json' -d '{"name":"Ada"}' URL. Since curl 7.82.0, --json '{"name":"Ada"}' does the same in one option and also sets Accept: application/json. Without the header, -d sends Content-Type: application/x-www-form-urlencoded, which many APIs reject.
Example against a local server
A small Node.js server prints what it receives:
cat > server.js <<'EOF'
const s = require("http").createServer((req, res) => {
let body = "";
req.on("data", (c) => (body += c));
req.on("end", () => res.end(`${req.method} type=${req.headers["content-type"]} accept=${req.headers["accept"]} body=${body}\n`));
});
s.listen(4310, "127.0.0.1");
setTimeout(() => process.exit(0), 5000);
EOF
node server.js &
sleep 1
URL=http://127.0.0.1:4310/users
curl -s -d '{"name":"Ada"}' "$URL"
curl -s -H 'Content-Type: application/json' -d '{"name":"Ada"}' "$URL"
curl -s --json '{"name":"Ada"}' "$URL"
echo '{"name":"Grace"}' > user.json
curl -s --json @user.json "$URL"Output
POST type=application/x-www-form-urlencoded accept=*/* body={"name":"Ada"}
POST type=application/json accept=*/* body={"name":"Ada"}
POST type=application/json accept=application/json body={"name":"Ada"}
POST type=application/json accept=application/json body={"name":"Grace"}The first request shows the wrong default content type; the others send JSON correctly. @file reads the body from a file, and @- from standard input.
Options
| Option | Effect |
|---|---|
| -d, --data DATA | Send DATA as the body of a POST (strips newlines when reading from a file) |
| --data-binary @file | Send the file exactly as it is, newlines included |
| --json DATA | Like --data-binary plus Content-Type and Accept set to application/json (curl 7.82.0+) |
| -H "Content-Type: application/json" | Set the content type explicitly |
| -X PUT / -X PATCH | Use another method with the same body options |
| -f / --fail-with-body | Exit with code 22 on HTTP 4xx/5xx; --fail-with-body also prints the response |
Quoting on Windows
In cmd.exe, single quotes are not quote characters, so escape the double quotes inside the JSON: curl -H "Content-Type: application/json" -d "{\"name\":\"Ada\"}" URL. In PowerShell, curl may be an alias of Invoke-WebRequest in Windows PowerShell 5.1; call curl.exe explicitly. Reading the body from a file with @user.json avoids quoting problems in every shell.