Google Analytics Data API v1 (impressions) data does not match with GA4 Analytics / Ads data

I want to retrieve Google Ads related data (impressions, clicks, cost) from a GA4 Google Analytics property (linked to my Google Ads account) using the new Google Analytics Data API v1. My code works, but it returns very different numbers compared to what I see in Google Analytics or Google Ads. For example for the week of 15-21 May:

My code using GA Data API v1 Google Analytics Google Ads
Impressions 2472 ? 4.17K
Clicks 324 339 353
Cost 92.3 95.7 98.23

As you can see there is a very big difference especially for the number of impressions. (Unfortunately I could not find a way to check this number in Analytics for a large number of campaigns as “Exploration reports” only work for 10 campaigns or so.) I see similar differences for all other weeks.

Please see below my php code retrieving the data from Analytics. What am I doing wrong that I’m not getting the same (impression) numbers as in Google Analytics/Ads?

public function handle()
{

    $downloader = new GNGGA4DataDownloader();
    $results = $downloader->run('2023-05-15', '2023-05-21', config('services.google-analytics.propertyID'));

    $ti = 0;
    $tcl = 0;
    $tco = 0; 

    foreach ($results as $r) {
        $ti += $r->impressions;
        $tcl += $r->clicks;
        $tco += $r->cost;
    }

    dd($results, 'impressions: ' . $ti, 'clicks: ' . $tcl, 'cost: ' . $tco);

}

<?php
namespace AppGNG;

use GoogleAnalyticsDataV1alphaOrderByDimensionOrderBy;
use GoogleAnalyticsDataV1betaBetaAnalyticsDataClient;
use GoogleAnalyticsDataV1betaDateRange;
use GoogleAnalyticsDataV1betaDimension;
use GoogleAnalyticsDataV1betaMetric;
use GoogleAnalyticsDataV1betaOrderBy;
use stdClass;

//This is the current API to download Analytics data from GA4 properties.
class GNGGA4DataDownloader 
{

    private function downloadData($startDate, $endDate, $ga_propertyID) {

        $path = storage_path('app/GA/GNG GA4 API-XXX.json');
        putenv("GOOGLE_APPLICATION_CREDENTIALS=" . $path);

        $client = new BetaAnalyticsDataClient();

        // Make an API call.
        $response = $client->runReport([
            'property' => 'properties/' . $ga_propertyID,
            'dateRanges' => [
                new DateRange([
                    'start_date' => $startDate,
                    'end_date' => $endDate,
                ]),
            ],
            'dimensions' => [
                new Dimension(['name' => 'sessionCampaignName']),
                //new Dimension(['name' => 'sessionGoogleAdsCampaignName']),
                
                new Dimension(['name' => 'year']),
                new Dimension(['name' => 'isoWeek']),
            ],
            'metrics' => [
                new Metric(['name' => 'advertiserAdImpressions']), 
                new Metric(['name' => 'advertiserAdClicks']), 
                new Metric(['name' => 'advertiserAdCost']), 
                
            ],
            'orderBys' => [
                new OrderBy([
                    'dimension' => new OrderByDimensionOrderBy([
                        'dimension_name' => 'sessionCampaignName', 
                        //'dimension_name' => 'sessionGoogleAdsCampaignName', 
                        'order_type' => OrderByDimensionOrderByOrderType::ALPHANUMERIC
                    ]),
                    'desc' => false,
                ]),
            ],
            'keepEmptyRows' => true,  
            
        ]);

        return $response;


    }

    private function extractResults($response) {

        $results = array();

        foreach ($response->getRows() as $row) {

            $d = new stdClass();

            $d->campaignCode = $row->getDimensionValues()[0]->getValue();
            $d->isoYear = $row->getDimensionValues()[1]->getValue();
            $d->isoWeek = $row->getDimensionValues()[2]->getValue();
            $d->impressions = $row->getMetricValues()[0]->getValue();
            $d->clicks = $row->getMetricValues()[1]->getValue();
            $d->cost = $row->getMetricValues()[2]->getValue();
         
            array_push($results, $d);

        }

        return $results;

    }
    
    function run($startDate, $endDate, $gaPropertyID) {

        $response = $this->downloadData($startDate, $endDate, $gaPropertyID);

        $results = $this->extractResults($response);

        return $results;

    }

}