276

I can successfully create a place via curl executing the following command:

$ curl -vX POST https://server/api/v1/places.json -d "
  auth_token=B8dsbz4HExMskqUa6Qhn& \
  place[name]=Fuelstation Central& \
  place[city]=Grossbeeren& \
  place[address]=Buschweg 1& \
  place[latitude]=52.3601& \
  place[longitude]=13.3332& \
  place[washing]=true& \
  place[founded_at_year]=2000& \
  place[products][]=diesel& \
  place[products][]=benzin \
"

The server returns HTTP/1.1 201 Created.
Now I want to store the payload in a JSON file which looks like this:

// testplace.json
{
  "auth_token" : "B8dsbz4HExMskqUa6Qhn",
  "name" : "Fuelstation Central",
  "city" : "Grossbeeren",
  "address" : "Buschweg 1",
  "latitude" : 52.3601,
  "longitude" : 13.3332,
  "washing" : true,
  "founded_at_year" : 2000,
  "products" : ["diesel","benzin"]
}

So I modify the command to be executed like this:

$ curl -vX POST http://server/api/v1/places.json -d @testplace.json

This fails returning HTTP/1.1 401 Unauthorized. Why?

2
  • 2
    Also keep in mind that if you're uploading binary files, you should use --data-binary. Commented Aug 7, 2019 at 0:18
  • 2
    For anyone referencing this question for an answer to 'how do I specify the file that contains the JSON', note that it's with the @ sign as given in the question e.g. $ curl -vX POST http://server/api/v1/places.json -d @testplace.json. This assumes that you are running curl from the directory that contains testplace.json - otherwise use e.g @/some/directory/some.json Commented Jun 1, 2021 at 6:07

3 Answers 3

456

curl sends POST requests with the default content type of application/x-www-form-urlencoded. If you want to send a JSON request, you will have to specify the correct content type header:

$ curl -vX POST http://server/api/v1/places.json -d @testplace.json \
--header "Content-Type: application/json"

But that will only work if the server accepts json input. The .json at the end of the url may only indicate that the output is json, it doesn't necessarily mean that it also will handle json input. The API documentation should give you a hint on whether it does or not.

The reason you get a 401 and not some other error is probably because the server can't extract the auth_token from your request.

2
  • 12
    I was trying to use cat file.json after the -d and was having trouble with it, until I learned from this answer that I can use @file.json. Thanks :)
    – Shadi
    Commented Jan 26, 2017 at 6:16
  • 1
    note that if you need multiple headers you need to specify -H/--header multiple times, at least when tested in bash on Ubuntu. Commented Sep 14, 2017 at 1:24
10

To clarify how to actually specify a file that contains the JSON to post, note that it's with the @ sign as shown in the OP

e.g. a typical post to a local .NET Core API:

curl -X POST https://localhost:5001/api -H "Content-Type: application/json" -d @/some/directory/some.json

4

You can cat the contents of a json file to curl via the --data-raw parameter

curl https://api.com/route -H 'Content-Type: application/json' --data-raw "$(cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//')"

curl https://api.com/route -H 'Content-Type: application/json' -d @<(jq . ~/.json/payload-2022-03-03.json)

curl https://api.com/route -H 'Content-Type: application/json' -d @<(jq '{"payload": .}' < ~/.json/payload-2022-03-03.json)

Note: comments in the json file are filtered out via grep -v '^\s*//'

You can also pass the data to curl via stdin using grep or cat or jq

grep -v '^\s*//' ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d @-

cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//' | curl https://api.com/route -H 'Content-Type: application/json' -d @-

jq . ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d @-

jq '{"payload": .}' < ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d @-

Not the answer you're looking for? Browse other questions tagged or ask your own question.