I’ve had the same problem and figured it out now.
The issue is that the JSON API plugin checks to see if a thumbnail file exists locally before it adds it to the JSON response. If it doesn’t exist it just omits it.
The problem is locating in json-api/models/attachment.php in the query_images
function at line 48.
You’ll need to change this
function query_images() {
$sizes = array('thumbnail', 'medium', 'large', 'full');
if (function_exists('get_intermediate_image_sizes')) {
$sizes = array_merge(array('full'), get_intermediate_image_sizes());
}
$this->images = array();
$home = get_bloginfo('url');
foreach ($sizes as $size) {
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
$filename = ABSPATH . substr($url, strlen($home) + 1);
if (file_exists($filename)) {
list($measured_width, $measured_height) = getimagesize($filename);
if ($measured_width == $width &&
$measured_height == $height) {
$this->images[$size] = (object) array(
'url' => $url,
'width' => $width,
'height' => $height
);
}
}
}
}
To this
function query_images() {
$sizes = array('thumbnail', 'medium', 'large', 'full');
if (function_exists('get_intermediate_image_sizes')) {
$sizes = array_merge(array('full'), get_intermediate_image_sizes());
}
$this->images = array();
$home = get_bloginfo('url');
foreach ($sizes as $size) {
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
$this->images[$size] = (object) array(
'url' => $url,
'width' => $width,
'height' => $height
);
}
}
And that will force the JSON api to return the S3 url and not bother checking if it exists locally