Send request data

Send JSON

Send a JSON request body with the correct content type and preserve the exact bytes from a file when needed.

JSON is the default language of HTTP APIs. For years, sending it with curl took three things: --data for the body, a --header for the content type, and careful quoting in between.

Modern curl (7.82.0 and later) has --json. It sends the body and adds the right Content-Type and Accept headers in one move.

Send an object

Send a small JSON object to an echo endpoint:

curl --json '{"name":"Mina","active":true}' https://httpbin.org/anything

httpbin returns the headers it saw and the body it parsed:

{
  "headers": {
    "Accept": "application/json",
    "Content-Type": "application/json"
  },
  "json": {
    "active": true,
    "name": "Mina"
  },
  "method": "POST"
}

Check three things in that echo.

The method became POST. Sending data implies it, so you didn’t have to ask.

Content-Type: application/json is there. That header tells the server how to parse the body. Without it, many frameworks refuse the request or ignore the body entirely.

And the json field proves the server parsed your object, not a mangled version of it.

Notice the single quotes around the JSON. They protect the double quotes inside from the shell. Get the quoting wrong and the server receives something like {name:Mina}, or the shell errors out before curl even runs. This is the most common failure with JSON in curl.

Send a file

For bigger documents, stop fighting shell quoting and read the body from a file:

curl --json @request.json https://httpbin.org/anything

The @ prefix reads the file byte for byte. No escaping, no quoting puzzles. And you can validate the file first:

jq . request.json

jq fails loudly on broken JSON, before the server ever sees it.

On an older curl

If your curl doesn’t have --json, assemble the same request by hand:

curl --data '{"name":"Mina","active":true}' --header 'Content-Type: application/json' https://httpbin.org/anything

Same bytes on the wire. --json just saves you the typing.

Keep credentials out of examples

Request bodies get pasted into tickets, committed in test scripts, and stored in shell history. Never put a long-lived API credential inside a JSON example, a command you type, or a committed script. A well-formed request with a real secret in it is still a leak.

One last thing. --json guarantees correct headers and intact bytes. It does not check that your JSON matches what the API expects. That contract is between you and the server, and the server will tell you when you got it wrong.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →