Google Search Console - v1.0.0
GET /performance
Returns the performance overview: totals across the range plus a daily trend series.
- Route name:
google-search-console.performance - Middleware:
web,auth - Controller:
ArtisanPackUI\GoogleSearchConsole\Http\Controllers\PerformanceOverviewController - Consumed by:
<PerformanceCard />(React) and<PerformanceCard />(Vue) viaresources/js/shared/performance.ts.
Query parameters
| Parameter | Type | Default | Clamp | Notes |
|---|---|---|---|---|
days |
int |
28 |
1..DateRange::MAX_DAYS |
Any non-scalar → 28. |
Behavior
Two searchAnalytics.query calls under the hood:
- Totals — no dimensions, aggregated across the range.
- Trend — dimension
date, one row per day.
The controller runs both via PerformanceOverviewFetcher::fetch() and returns the resulting PerformanceOverviewData::toArray().
Successful response
{
"range": {
"startDate": "2026-01-01",
"endDate": "2026-01-28"
},
"totals": {
"clicks": 1234,
"impressions": 45678,
"ctr": 0.027,
"position": 12.3
},
"trend": [
{ "date": "2026-01-01", "clicks": 42, "impressions": 500, "ctr": 0.084, "position": 3.2 },
{ "date": "2026-01-02", "clicks": 51, "impressions": 620, "ctr": 0.082, "position": 3.1 }
],
"hasData": true
}
hasData
true when either call returned at least one row. false when both calls returned an empty rows array — a fresh Search Console property, a range in the last 2–3 finalising days, or an account with genuine zero traffic. The distinction matters because the API returns {} (no rows key) rather than a row of zeros, which would otherwise fold into totals = { clicks: 0, impressions: 0, ... } and misrepresent as "0 clicks this week". Components render an explicit empty state instead.
range
Echoes the resolved date range so the client doesn't have to compute it. startDate is inclusive; endDate is inclusive.
Error responses
Standard shape (see HTTP Endpoints#Error response shapes):
401 unauthenticated— no signed-in user.409 not_connected— user has no connected Google account.501 base_not_installed— base package missing.502 reporting_error— the API call failed.
Example calls
# Last 28 days (default)
curl 'https://your-app.test/google-search-console/performance' \
--cookie 'laravel_session=...'
# Last 90 days
curl 'https://your-app.test/google-search-console/performance?days=90' \
--cookie 'laravel_session=...'
# Invalid range (non-numeric)
curl 'https://your-app.test/google-search-console/performance?days=abc' \
--cookie 'laravel_session=...'
# → falls back to days=28
Testing
Http::fakeSequence()
->push( [ 'rows' => [ [ 'keys' => [], 'clicks' => 42, 'impressions' => 500, 'ctr' => 0.084, 'position' => 3.2 ] ] ], 200 )
->push( [ 'rows' => [ [ 'keys' => [ '2026-01-01' ], 'clicks' => 42, 'impressions' => 500, 'ctr' => 0.084, 'position' => 3.2 ] ] ], 200 );
$this->actingAs( $user )
->getJson( '/google-search-console/performance?days=7' )
->assertOk()
->assertJsonPath( 'hasData', true )
->assertJsonPath( 'totals.clicks', 42.0 );