Skip to content
Woodander Docs
EN

GA4

Google Analytics 4 summary, pages and traffic sources, with live custom ranges, metrics and filters.

4 endpoints. Each one is a REST endpoint under https://woodander.com/api/v1 and an MCP tool with the same name and arguments. See the overview for authentication, rate limits and errors.

ga4_summary

GET /api/v1/sites/{site}/ga4/summary

Google Analytics (GA4) sessions, users, engaged sessions and key events for a period, the previous period, the daily series, countries and devices. Served from synced data of the property you chose for the site; with a longer or custom range, compare, metrics or filters it is a live Data API report (cached for an hour).

MCP tool ga4_summary Scope read:analytics Plan Pro and above

Parameters

NameInTypeRequiredDescription
site path string Yes Host of one of your sites, e.g. example.com (see list_sites).
range query string No Period ending yesterday. Default 28d. 3m and longer are live from Google. One of: 28d, 90d, 3m, 6m, 12m, 16m.
from query string No With to: a custom date range (YYYY-MM-DD), up to 16 months back. Answered live from Google (cached for an hour).
to query string No End of the custom date range (YYYY-MM-DD), not in the future.
compare query string No Compare with the previous period of the same length, or the same dates a year earlier (live). One of: none, previous, year.
metrics query array<string> No GA4 metrics to return (live): sessions, totalUsers, newUsers, engagedSessions, engagementRate, bounceRate, screenPageViews, eventCount, keyEvents, sessionKeyEventRate, averageSessionDuration, userEngagementDuration. Rates are percentages.
filters query array<object> No Up to 8 conditions, all must match (live): a list of {"dimension": a GA4 dimension such as pagePath, sessionSource, country, deviceCategory, eventName, "operator": "contains|not_contains|equals|not_equals|regex|not_regex", "value"}. Regular expressions use RE2 syntax. In Search Console country is a 3-letter code (deu) and device is desktop, mobile or tablet.

Example request

bash
curl "https://woodander.com/api/v1/sites/example.com/ga4/summary" \
  -H "Authorization: Bearer wdr_..."
tools/call
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "ga4_summary",
        "arguments": {
            "site": "example.com"
        }
    }
}

Example response Example

json
{
    "data": {
        "site": "example.com",
        "property": "properties/123456789",
        "range": {
            "key": "28d",
            "days": 28,
            "through": "2026-10-16"
        },
        "totals": {
            "sessions": 5200,
            "users": 3900,
            "engaged_sessions": 3100,
            "engagement_rate": 59.6,
            "key_events": 140
        },
        "previous_period": {
            "sessions": 4800,
            "users": null,
            "engaged_sessions": 2800,
            "engagement_rate": 58.3,
            "key_events": 120
        },
        "daily": [
            {
                "date": "2026-10-16",
                "sessions": 180,
                "users": 150,
                "engaged_sessions": 110,
                "key_events": 5
            }
        ],
        "countries": [
            {
                "value": "United States",
                "sessions": 1200,
                "users": 900,
                "engaged_sessions": 800,
                "engagement_rate": 66.7,
                "key_events": 30
            }
        ],
        "devices": [
            {
                "value": "mobile",
                "sessions": 1200,
                "users": 900,
                "engaged_sessions": 800,
                "engagement_rate": 66.7,
                "key_events": 30
            }
        ]
    },
    "meta": {
        "synced_at": "2026-10-17T03:45:00+00:00",
        "source": "synced_google_analytics"
    }
}

Errors

HTTPCodeMeaning
401unauthenticatedMissing, invalid, expired or revoked token.
403insufficient_scopeThe token does not have the read:analytics scope.
403plan_requiredThe plan does not include API access.
404not_foundNot found, or not yours.
422invalid_requestA parameter is not valid (range, type, cursor).
429rate_limitedToo many requests. See the Retry-After header.

ga4_pages

GET /api/v1/sites/{site}/ga4/pages

Top pages by Google Analytics sessions for 28 or 90 days (the synced snapshot), sortable and filterable. With a longer or custom range, compare, dimension, metrics or filters it is a live Data API report (cached for an hour).

MCP tool ga4_pages Scope read:analytics Plan Pro and above

Parameters

NameInTypeRequiredDescription
site path string Yes Host of one of your sites, e.g. example.com (see list_sites).
range query string No Period ending yesterday. Default 28d. 3m and longer are live from Google. One of: 28d, 90d, 3m, 6m, 12m, 16m.
from query string No With to: a custom date range (YYYY-MM-DD), up to 16 months back. Answered live from Google (cached for an hour).
to query string No End of the custom date range (YYYY-MM-DD), not in the future.
compare query string No Compare with the previous period of the same length, or the same dates a year earlier (live). One of: none, previous, year.
dimension query string No Group the rows by this GA4 dimension instead of the default (live), e.g. country, deviceCategory, sessionDefaultChannelGroup, eventName, landingPage, date.
metrics query array<string> No GA4 metrics to return (live): sessions, totalUsers, newUsers, engagedSessions, engagementRate, bounceRate, screenPageViews, eventCount, keyEvents, sessionKeyEventRate, averageSessionDuration, userEngagementDuration. Rates are percentages.
filters query array<object> No Up to 8 conditions, all must match (live): a list of {"dimension": a GA4 dimension such as pagePath, sessionSource, country, deviceCategory, eventName, "operator": "contains|not_contains|equals|not_equals|regex|not_regex", "value"}. Regular expressions use RE2 syntax. In Search Console country is a 3-letter code (deu) and device is desktop, mobile or tablet.
filter query string No Keep page paths containing this text.
sort query string No Default sessions. One of: sessions, users, engaged_sessions, key_events.
limit query integer No Page size, 1 to 100.
cursor query string No meta.next_cursor of the previous page.

Example request

bash
curl "https://woodander.com/api/v1/sites/example.com/ga4/pages" \
  -H "Authorization: Bearer wdr_..."
tools/call
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "ga4_pages",
        "arguments": {
            "site": "example.com"
        }
    }
}

Example response Example

json
{
    "data": [
        {
            "value": "/blog/guide",
            "sessions": 1200,
            "users": 900,
            "engaged_sessions": 800,
            "engagement_rate": 66.7,
            "key_events": 30
        }
    ],
    "meta": {
        "next_cursor": null,
        "limit": 25,
        "total": 1,
        "site": "example.com",
        "dimension": "page_path",
        "range": "28d",
        "sort": "sessions",
        "synced_at": "2026-10-17T03:45:00+00:00"
    }
}

Errors

HTTPCodeMeaning
401unauthenticatedMissing, invalid, expired or revoked token.
403insufficient_scopeThe token does not have the read:analytics scope.
403plan_requiredThe plan does not include API access.
404not_foundNot found, or not yours.
422invalid_requestA parameter is not valid (range, type, cursor).
429rate_limitedToo many requests. See the Retry-After header.

ga4_sources

GET /api/v1/sites/{site}/ga4/sources

Traffic sources (source / medium, e.g. google / organic) by Google Analytics sessions for 28 or 90 days (the synced snapshot), sortable and filterable. With a longer or custom range, compare, dimension, metrics or filters it is a live Data API report (cached for an hour).

MCP tool ga4_sources Scope read:analytics Plan Pro and above

Parameters

NameInTypeRequiredDescription
site path string Yes Host of one of your sites, e.g. example.com (see list_sites).
range query string No Period ending yesterday. Default 28d. 3m and longer are live from Google. One of: 28d, 90d, 3m, 6m, 12m, 16m.
from query string No With to: a custom date range (YYYY-MM-DD), up to 16 months back. Answered live from Google (cached for an hour).
to query string No End of the custom date range (YYYY-MM-DD), not in the future.
compare query string No Compare with the previous period of the same length, or the same dates a year earlier (live). One of: none, previous, year.
dimension query string No Group the rows by this GA4 dimension instead of the default (live), e.g. country, deviceCategory, sessionDefaultChannelGroup, eventName, landingPage, date.
metrics query array<string> No GA4 metrics to return (live): sessions, totalUsers, newUsers, engagedSessions, engagementRate, bounceRate, screenPageViews, eventCount, keyEvents, sessionKeyEventRate, averageSessionDuration, userEngagementDuration. Rates are percentages.
filters query array<object> No Up to 8 conditions, all must match (live): a list of {"dimension": a GA4 dimension such as pagePath, sessionSource, country, deviceCategory, eventName, "operator": "contains|not_contains|equals|not_equals|regex|not_regex", "value"}. Regular expressions use RE2 syntax. In Search Console country is a 3-letter code (deu) and device is desktop, mobile or tablet.
filter query string No Keep sources containing this text.
sort query string No Default sessions. One of: sessions, users, engaged_sessions, key_events.
limit query integer No Page size, 1 to 100.
cursor query string No meta.next_cursor of the previous page.

Example request

bash
curl "https://woodander.com/api/v1/sites/example.com/ga4/sources" \
  -H "Authorization: Bearer wdr_..."
tools/call
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "ga4_sources",
        "arguments": {
            "site": "example.com"
        }
    }
}

Example response Example

json
{
    "data": [
        {
            "value": "google / organic",
            "sessions": 1200,
            "users": 900,
            "engaged_sessions": 800,
            "engagement_rate": 66.7,
            "key_events": 30
        }
    ],
    "meta": {
        "next_cursor": null,
        "limit": 25,
        "total": 1,
        "site": "example.com",
        "dimension": "source_medium",
        "range": "28d",
        "sort": "sessions",
        "synced_at": "2026-10-17T03:45:00+00:00"
    }
}

Errors

HTTPCodeMeaning
401unauthenticatedMissing, invalid, expired or revoked token.
403insufficient_scopeThe token does not have the read:analytics scope.
403plan_requiredThe plan does not include API access.
404not_foundNot found, or not yours.
422invalid_requestA parameter is not valid (range, type, cursor).
429rate_limitedToo many requests. See the Retry-After header.

queue_ga4_sync

POST /api/v1/sites/{site}/ga4/sync

Queue a refresh of the stored Google Analytics (GA4) figures of one of your sites. Refused while the figures are under 15 minutes old. What happens depends on the mode the owner set for this module in Settings → AI activity: Manual stores a proposal the owner applies in the Workspace (the answer has a confirm_url), Hybrid and Autonomous run it. Poll agent_change_status with the id.

MCP tool queue_ga4_sync Scope run:audits Plan Pro and above

Parameters

NameInTypeRequiredDescription
site path string Yes Host of one of your sites (see list_sites).

Example request

bash
curl -X POST "https://woodander.com/api/v1/sites/example.com/ga4/sync" \
  -H "Authorization: Bearer wdr_..."
tools/call
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "queue_ga4_sync",
        "arguments": {
            "site": "example.com"
        }
    }
}

Example response Example

json
{
    "data": {
        "id": 41,
        "action": "seo.queue_ga4_sync",
        "risk": "reversible",
        "status": "done",
        "needs": null,
        "summary": "Refresh the Google Analytics figures of example.com",
        "diff": [],
        "requested_by": "Token “Claude Code”",
        "note": null,
        "error": null,
        "result": {
            "summary": "Google Analytics refresh of example.com queued."
        },
        "confirm_url": null,
        "created_at": "2026-10-19T09:00:00+00:00",
        "decided_at": null
    },
    "meta": {
        "outcome": "done",
        "module": "seo",
        "mode": "hybrid",
        "hint": null
    }
}

Errors

HTTPCodeMeaning
401unauthenticatedMissing, invalid, expired or revoked token.
403insufficient_scopeThe token does not have the run:audits scope.
403plan_requiredThe plan does not include API access.
404not_foundNot found, or not yours.
429rate_limitedToo many requests. See the Retry-After header.