Search code examples
phpjsonapicurlgoogle-cloud-vision

Google Cloud Vision API 400 Invalid JSON Payload


I have entered all of the required fields as they write on protocol section in https://cloud.google.com/vision/docs/detecting-labels#vision-label-detection-protocol as i wrote my code below. But, still it return 400 error.

<?php
if(!isset($googleapikey)){
    include('settings.php');
}
function vision($query){
    global $googleapikey;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,'https://vision.googleapis.com/v1/images:annotate?key='.$googleapikey);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
    $result = curl_exec ($ch);
    curl_close ($ch);
    return $result;
}

$vdata = array();
$vdata['requests'][0]['image']['source']['imageUri'] = 'https://cloud.google.com/vision/docs/images/ferris-wheel.jpg';
$vdata['requests'][0]['features'][0]['type'] = 'LABEL_DETECTION';
echo vision(json_encode($vdata));
?>

Solution

  • Your only error in the request to Cloud Vision API is that you are not setting propery the HTTP Header field Content-type: application/json, because you are not assigning it to the right variable (you are pointing to $curl instead of $ch):

    // Insread of this:
    curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
    // Use this:
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
    

    The error shown when running your old code was the one below, which indicated that the query was not understanding the content data as JSON.

    Cannot bind query parameter. Field '{\"requests\":[{\"image\":{\"source\":{\"imageU ri\":\"https://cloud' could not be found in request message.
    

    As a side note, let me recommend you the Client Libraries for Cloud Vision API, which have some nice documentation and can make your life easier when working with some of the APIs in Google Cloud Platform from a script. In this case, you would not need to force a curl command, and you could achieve the same results with a much simple (and understandable) code, such as:

    <?php
    require __DIR__ . '/vendor/autoload.php';
    use Google\Cloud\Vision\VisionClient;
    
    $projectId = '<YOUR_PROJECT_ID>';
    $vision = new VisionClient([
        'projectId' => $projectId
    ]);
    
    $fileName = 'https://cloud.google.com/vision/docs/images/ferris-wheel.jpg';
    $image = $vision->image(file_get_contents($fileName), ['LABEL_DETECTION']);
    $labels = $vision->annotate($image)->labels();
    
    echo "Labels:\n";
    foreach ($labels as $label) {
        echo $label->description() . "\n";
    }
    ?>