I am having trouble when uploading media to a WordPress site with the JSON REST API.

With the following code I can upload the photos, but no info is assigned to them, not even the name - in fact the name automatically becomes the URL and filename (without the extension).

$username = "ZX";
$password = "ZX";
$host = 'http://ZX.com/wp-json/wp/v2/media';
$data = json_encode($data);
$file = '/Users/xx.png';
$imagedata  = file_get_contents($file);
$process = curl_init($host); 
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($process, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($process, CURLOPT_TIMEOUT, 50);
curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($process, CURLOPT_POSTFIELDS, $data);
curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type:image/png','Content-Disposition:attachment;filename='.$file));
$return = curl_exec($process);

How would I assign data, like the following, to the uploads?

$data = array(
  "status" => "draft",
  "title" => "Photo media",       
  "description" => "Photo media1",
  "media_type" => "image",
  "alt_text" => "alternate text"

This is not possible via the API; you need to fetch the image yourself, and send the data to the API yourself. Blockquote

– This quotes Ryan on the GitHub–issue mentioned in @Dan (deleted) answer.

How to side load images

Note that the media_sideload_image() return value can be an instance of \WP_Error as well. You then just need to attach it to a post, which is quite simple:

$media = media_sideload_image( 
    'Some image description', 

if ( ! empty( $media ) and ! is_wp_error( $media ) ) {
    // reference new image to set as featured
    $attachments = get_posts( [
        'post_type'      => 'attachment',
        'posts_per_page' => 1,
        'post_status'    => 'any',
        'post_parent'    => $post->ID,
    ] );

    if ( is_array( $attachments ) ) {
        set_post_thumbnail( $post->ID, $attachments[0]->ID );

    // Test print our image. The return value is the src of the sideloaded image.
    printf( '<img src="%s" />', $media );

The internals

A short back trace through core that explains why you should stick with the API:

Take a look at the source of media_sideload_image() to see it uses download_url() internally, which uses wp_safe_remote_get(), a wrapper for \WP_HTTP::get(). This means it offers the whole WP API while being quite safe, debuggable and easy to use. The return value of download_url() is the result of wp_tempnam(), which takes all possible /tmp locations into account (there are plenty) and makes sure your location is writeable. The media_handle_sideload() will generate all needed attachment data and meta data.

  • Which is the cited question? Is this method still valid? – Brethlosze Jan 16 '19 at 18:20
  • See update and GitHub–Issue link in the quote. And why would it not be valid? If you want to check again, just follow down the rabbit hole along the lines of The internals and compare the current WP–version with the code linked here. That's not that hard. – kaiser Jan 16 '19 at 23:45
  • Because this answer is from 2016. I just want to make sure that as of 2019, the REST API cannot deal with uploading files into media objects, hence one can focus on WP functions. – Brethlosze Jan 17 '19 at 0:12
  • @Brethlosze as I said: Please take a look for yourself around core code. I do not have any fresh info on that topic as I am not working with WP much right now. – kaiser Jan 17 '19 at 1:02

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.