How to POST JSON Using cURL?

Use the --json option to send JSON in a cURL POST request. Pass the JSON body directly after the option. cURL sends a POST request and automatically sets the Content-Type: application/json and Accept: application/json headers.

Send JSON Directly in the cURL Command

You can use this method when the JSON payload is short enough to include directly in the terminal command.

We will first send a name and age as a JSON body to our hosted version of HTTPBin:

curl --json '{"name":"John","age":30}' \
 https://httpbin.scrapingbee.com/post

The --json option sends the provided value as JSON. Because request data is provided, cURL uses the POST method automatically.

The response confirms that the server received and parsed the JSON body as seen below:

Terminal output showing the HTTPBin response to a cURL --json POST request, with the parsed JSON body and the automatic JSON headers

The json field contains the parsed payload. The headers section also shows that cURL added the JSON content and accept headers automatically.

POST JSON with -H and -d

Use -H and -d flags when working with a cURL version that does not support --json. The --json option was added in cURL 7.82.0.

In the example below, -H sets the request content type to JSON, while -d adds the JSON body:

curl -H "Content-Type: application/json" \
 -d '{"name":"John","age":30}' \
 https://httpbin.scrapingbee.com/post

As seen here, the response contains the submitted values:

Terminal output showing the HTTPBin response to a cURL POST request that sets Content-Type with -H and the JSON body with -d

Note that -d only sets the content type you pass with -H. It does not add an Accept header, so the response shows "Accept": "*/*".

POST JSON from a File

Use a JSON file when the request body is too long or complex to include directly in the terminal.

First, we need the JSON file with a payload, example data.json:

{
 "name": "John",
 "age": 30
}

Then you use the @data.json to tell cURL to read the request body from that file:

curl --json @data.json \
 https://httpbin.scrapingbee.com/post

The response as shown below confirms that the content of the JSON file was sent and parsed:

Terminal output showing the HTTPBin response to a cURL --json POST request that reads its body from a data.json file

For older cURL versions, send the same file with -d and set the content type manually:

curl -H "Content-Type: application/json" \
 -d @data.json \
 https://httpbin.scrapingbee.com/post

Keep in mind that -d strips newlines from the file, while --json sends its contents as they are. Both send a valid JSON body, so the server parses them identically.

Related curl web scraping questions: