What Data Can You Retrieve from the GA4 Integration in OpenSEO?

The GA4 integration in OpenSEO exposes connection metadata, organic search totals (sessions, active users, engagement rate, key events), period-over-period comparisons, daily time-series trends, diagnostic warnings, and real-time API quota status.

The every-app/open-seo repository implements a comprehensive Google Analytics 4 (GA4) integration that queries specific organic-search metrics through a dedicated service layer. Once a GA4 property is linked to a project, the platform aggregates this data to populate dashboard visualizations and API endpoints.

Connection Metadata and Property Selection

Before retrieving analytics, OpenSEO verifies connection status and enumerates available properties. The getGa4Connection function in src/serverFunctions/ga4.ts invokes Ga4Service.getConnection to return a connection payload containing:

  • connected – Boolean indicating active linkage
  • currentUserHasGrant – OAuth permission status
  • propertyId, propertyDisplayName, propertyTimeZone, propertyCurrencyCode – Property configuration
  • connectedByEmail, connectedAt – Audit timestamps

To populate property selection dropdowns, listGa4Properties calls Ga4Service.listPropertiesForUserWithGrantStatus and decorates each entry with an isSelected flag. This allows users to distinguish the currently active property from other accessible accounts.

Organic Search Performance Metrics

Core organic metrics are retrieved via Ga4OrganicOverviewService.getOrganicOverview as implemented in src/server/features/ga4/services/Ga4OrganicOverviewService.ts. The service queries GA4 for the most recent 28-day period and returns:

  • totals – Aggregated sessions, activeUsers, engagementRate, and keyEvents
  • prevTotals – Matching metrics for the preceding equal-length period

These values power the dashboard's "Organic Overview" cards, providing immediate visibility into current performance versus historical baselines.

For trend visualization, OpenSEO transforms GA4's sparse row data into a continuous time-series. The getGa4DashboardReport function utilizes a helper called fillDailySessions (defined in src/serverFunctions/ga4.ts) to zero-fill days lacking data, ensuring chart continuity.

The resulting trend array contains objects with date and sessions fields, representing daily organic traffic across the selected date range. This normalization prevents gaps in line charts when GA4 returns null values for low-traffic days.

Metric Comparisons and Diagnostic Warnings

Period-over-period analysis is computed automatically. The service calculates metricComparison using comparisonValue logic, returning a comparison object with percentage changes for each metric (sessions, active users, engagement rate, key events).

Diagnostic capabilities include:

  • keyEventDiagnostics – Generates warnings when keyEvents drops by more than 50% and the previous value was ≥ 5
  • hasLimitedData – Propagates GA4's native data-quality flags when sample thresholds are exceeded
  • Date-range warnings – Alerts for invalid or restricted reporting windows

Quota Monitoring and Error Handling

Every dashboard request includes quota metadata extracted from the trend report (or fallback sources), indicating remaining API calls and time-window constraints. This prevents silent failures as users approach GA4's rate limits.

Error states are handled gracefully through Ga4ReportError in src/server/lib/ga4Errors.ts. Specific codes trigger connection fallbacks:

  • ga4_not_connected – Property never linked
  • ga4_reconnect_required – Expired OAuth or revoked permissions
  • ga4_property_inaccessible – Deleted or permission-removed property

When getGa4DashboardReport catches these errors, it returns { connected: false }, prompting the UI to display reconnection workflows.

Code Examples

Fetch the dashboard report client-side to access all available GA4 data:

import { getGa4DashboardReport } from '@/serverFunctions/ga4';

async function loadGa4Report(projectId: string) {
  const { data } = await getGa4DashboardReport({ projectId });
  if (!data.connected) {
    // Prompt the user to connect GA4
    return;
  }
  console.log('Current sessions:', data.totals.sessions);
  console.log('Trend (last 28 days):', data.trend);
  console.log('Comparison vs prior period:', data.comparison);
}

Access organic overview data directly on the server:

import { Ga4OrganicOverviewService } from '@/server/features/ga4/services/Ga4OrganicOverviewService';

async function getOrganicOverview(projectId: string) {
  const overview = await Ga4OrganicOverviewService.getOrganicOverview({ projectId });
  // `overview` contains totals, prevTotals, comparison, trend, and diagnostics
  return overview;
}

Summary

  • Connection metadata includes property IDs, timezones, currencies, and OAuth grant status retrieved via getGa4Connection.
  • Performance totals cover sessions, active users, engagement rate, and key events for current and previous periods.
  • Trend data provides zero-filled daily session counts via fillDailySessions for continuous charting.
  • Comparisons automatically calculate percentage changes across all core metrics.
  • Diagnostics detect significant key event drops and limited-data flags from GA4.
  • Quota tracking monitors API usage limits in real-time, while specific error codes (ga4_not_connected, ga4_reconnect_required) enable graceful fallback handling.

Frequently Asked Questions

OpenSEO tracks sessions, active users, engagement rate, and key events as defined in src/server/features/ga4/services/Ga4ReportDefinitions.ts. These metrics populate the totals and prevTotals objects in the dashboard response, providing a direct view of organic search performance without paid traffic interference.

How does OpenSEO handle gaps in GA4 historical data?

The platform uses the fillDailySessions helper in src/serverFunctions/ga4.ts to transform GA4's sparse row output into a continuous array. Days without recorded sessions receive explicit sessions: 0 entries, ensuring that line charts render correctly without interpolation artifacts or broken segments.

What happens when GA4 quota limits are reached in OpenSEO?

Each dashboard response includes a quota object indicating remaining API capacity. If limits are exceeded, subsequent requests will fail with Ga4ReportError, triggering the UI to display appropriate messaging. The system prioritizes quota data from the trend report, falling back to current report metadata when necessary.

How does OpenSEO detect significant drops in organic performance?

The keyEventDiagnostics function in Ga4OrganicOverviewService.ts automatically flags when key events decline by more than 50% compared to the previous period, provided the baseline was at least 5 events. This generates a warning object in the response that the dashboard surfaces as a visual alert, enabling rapid response to traffic anomalies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →