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.

10 minute lesson

~~~

JSON is the default language of HTTP APIs, and for years sending it with curl meant three options: --data for the body, a --header for the content type, and careful quoting in between. Modern curl (7.82.0 and later) provides --json, which sends JSON data and adds suitable Content-Type and Accept headers in one move.

Send an object

Send a small JSON object:

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

Inspect the echoed headers and parsed body:

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

Three things to verify in that echo. The method became POST, because sending data implies it. Content-Type: application/json 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.

Note the single quotes around the JSON. They protect the double quotes inside from the shell. This is the most common failure: with the quoting wrong, the server receives {name:Mina} or a shell error appears before curl even runs.

Send a file

For larger documents, use --json @request.json instead of fighting shell quoting:

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

The @ prefix reads the body from the file, byte for byte. No escaping, no quoting puzzles, and the file can be validated first with a tool like jq . request.json, which fails loudly on broken JSON before the server ever sees it.

On an older curl without --json, the equivalent is explicit:

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

Same request on the wire, just assembled by hand.

Keep credentials out of examples

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

The server still decides whether the JSON shape is valid. --json guarantees correct headers and intact bytes — the schema contract is between you and the API.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →