I am having this exact question, asked in 2015, about adding media through the WP REST API.

My code so far:

curl -s -X POST http://www.example.com/wp-json/wp/v2/media/ -H "Content-Type: application/json" -H "Content-Disposition: attachment; filename=image.png" -H "Authorization: Basic $base64credentials " -d '{"title":"mymedia", "alt-text":"", "caption":"", "description":"", "slug":"myslug", "status":"publish", "date":"2019-01-16T00:00:00", "post":$id}'

My result so far:

{"code":"rest_upload_sideload_error","message":"Sorry, this file type is not permitted for security reasons.","data":{"status":500}}

When I replace the extension by .txt, the call works, even if the file do not exist (??), and generates a corrupt empty media object. Other calls for post creation and post updates work fine. By switching into https server, and using the curl -k option, the same happens.

  • Do a Basic Authorization or HTTP or HTTPS problem might be the cause?

  • How should this be done today?

  • I am missing some header or syntax?


I suspect based on an answer at StackOverflow that something like this would work:

base64credentials="...... "
curl --request POST \
--url "http://www.yoursite.com/wp-json/wp/v2/media" \
--header "cache-control: no-cache" \
--header "content-disposition: attachment; filename=tmp" \
--header "authorization: Basic $base64credentials" \
--header "content-type: image/png" \
--data-binary "@/home/web/tmp.png" \

This should use tmp.png to create and upload a brand new attachment. You can then parse the result to retrieve the ID or success/failure and do other things with it, such as setting featured image meta etc.

I did notice the capitalisation of Authorization needed adjusting, and you'll want to adjust the content type and data binary parameters to match your target file, let me know how that goes


First, your content-type should be image/jpeg and not application/json, remember that content-type is supposed to reflect the data that you are passing and the POST media request expects an image.

Another change you have to make to accommodate the content-type is the way that you are passing the data. Instead of sending it with the source_url parameter, try passing it as a binary file.

One last thing I would mention is that the wp/v2 calls return 3XX status on a few occasions. It would be useful to follow those redirects and redo those requests to those new URLs.

| improve this answer | |
  • The solution works, though requires two calls. First should be for creation and upload: curl -sk --request POST --url https:/www.example.com/wp-json/wp/v2/media/$id --header "cache-control: no-cache" --header "content-disposition: attachment; filename=file.png" --header "authorization: Basic $base64credentials " --header "content-type: image/png" --data-binary "@$local/fullpath/file.png" --location – Brethlosze Jan 19 '19 at 6:56
  • Second should be for adding the data curl -sk --request POST --url https://www.example.com/wp-json/wp/v2/media/$id --header "authorization: Basic $base64credentials " --header "content-type: application/json" -d '{"title":"$title", "caption":"$caption", "description":"$description", "alt_text":"$alttext", "date":"$date", "slug":"$slug", "post":"$idpost", "status":"publish" }' – Brethlosze Jan 19 '19 at 6:58
  • Still, those steps do not make the media set as featured at the post. Which perhaps should be solved in another call. – Brethlosze Jan 19 '19 at 6:59
  • setting a featured image is a new problem that was not mentioned in the original question, and should be asked in a new question – Tom J Nowell Jan 19 '19 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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