The command
curl https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name":"Ada","role":"admin"}'
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
| Flag | What it does |
|---|---|
-H "Content-Type: application/json" | Declares the body as JSON. Without it, -d says form data. |
-d data | The JSON text. Its presence makes the request a POST. |
--json data | Shorthand for -d plus JSON Content-Type and Accept headers (curl 7.82+). |
-d @file.json | Read the body from a file. |
The --json shortcut
Since curl 7.82, --json does the whole job: it sends the data, sets Content-Type: application/json and adds Accept: application/json. Older systems still ship older curls, so scripts that must run everywhere should keep the explicit header form. Check with curl --version.
curl --json '{"name":"Ada","role":"admin"}' https://httpbin.org/post
# from a file, or from another program's output
curl --json @user.json https://httpbin.org/post
jq -n '{name:"Ada"}' | curl --json @- https://httpbin.org/post
Quoting JSON in a shell
JSON is full of double quotes, so wrap it in single quotes and the shell leaves it alone. That also stops variable expansion; to insert a shell variable, close the single quote, add the variable in double quotes, and reopen, or build the JSON with jq so the value is escaped properly.
Windows cmd.exe has no single-quote strings. Escape every inner quote with a backslash, or sidestep the problem by keeping the JSON in a file.
# Linux, macOS, Git Bash
name="Ada"
curl -H "Content-Type: application/json" \
-d '{"name":"'"$name"'"}' https://httpbin.org/post
# Windows cmd.exe
curl -H "Content-Type: application/json" -d "{\"name\":\"Ada\"}" https://httpbin.org/post
# any shell
curl -H "Content-Type: application/json" -d @user.json https://httpbin.org/post
Common mistakes
- A
415or an empty parsed body almost always means theContent-Typeheader is missing. - A
400with a parse error usually means the shell changed your quotes. Add-v, or post to an echo endpoint such as httpbin, and look at what was actually sent. -d @fileremoves newlines. Harmless for JSON structure, but it corrupts a multi-line string value; use--data-binary @filewhen exact bytes matter.
Related curl examples
Curl JSON Request Example
A JSON API call has two sides, the JSON you send and the JSON you get back, and each has its own header.
Curl GET JSON Example
Fetching JSON is a GET with one header that says what you want back.
Curl POST Example
Curl switches to POST the moment you give it a body.
Curl Content-Type Example
Content-Type tells the server how to parse the body you sent.
Webhook Examples
JSON POSTs as providers really send them, with headers and signatures.
What Is JSON?
The six data types and the syntax rules a JSON body has to follow.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under Request bodies
References
- curl man page: --json — The shortcut that sets the body and both JSON headers.
- MDN: Content-Type — The header that tells the server how to parse the body.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I POST JSON with curl?
Send the JSON with -d and add -H "Content-Type: application/json", or on curl 7.82 and later use --json with the JSON text, which sets the headers for you.
Why is my JSON body empty on the server?
Most often because the Content-Type header was not set, so curl sent application/x-www-form-urlencoded and the server did not run its JSON parser.
How do I send a JSON file with curl?
Use -d @file.json together with the JSON Content-Type header, or --json @file.json. Use --data-binary @file.json if line breaks inside the file must be preserved.