GA4 “Unexpected Field(s)” Error: Windsor Field Names vs GA4 API Names

If you request Google Analytics 4 data through Windsor.ai and see “Unexpected field(s): {total_users}. Please check the supported field list (https://windsor.ai/data-field/googleanalytics4/)”, the request used a field name that does not exist in Windsor’s GA4 connector. Windsor checks names before calling Google, so nothing was sent and nothing is wrong with your property.

This is the most common GA4 error we see, and by a wide margin the most common one AI assistants cause: they type the GA4 API name (totalUsers), a snake_case version of it (total_users), or the label from the GA4 interface (Views), where Windsor expects its own field ID. The fix is a lookup, and the table below covers the names that come up most.

Why this happens

Windsor gives every connector its own flat set of field IDs so the same request format works across 350+ sources. For GA4 the IDs are mostly snake_case versions of Google’s API names (screen_page_views, event_count, session_source_medium), but a handful of the oldest fields are lowercase with no underscore (totalusers, newusers, totalrevenue, pagetitle, transactionid), and a few carry a different word altogether (conversions is Google’s keyEvents; source is sessionSource). Google’s camelCase names are never accepted as-is.

There is no fuzzy matching. total_users, totalUsers and Total users all fail; only totalusers works. When several names fail in one request the error lists all of them in the braces, so fix every name before retrying.

The complete list is in the Google Analytics 4 field reference. Through the Windsor MCP connector, the get_fields tool returns the same list, and Claude or ChatGPT should call it before the first data request rather than guess.

The names people guess most, and the Windsor field to use

Ranked by how often each wrong name appears in GA4 requests. Where two Windsor IDs are listed, both work and return the same data.

You typed Use this Windsor field GA4 API name behind it
total_users, totalUsers totalusers totalUsers
new_users, newUsers newusers newUsers
device_category, deviceCategory devicecategory deviceCategory
session_source, sessionSource source sessionSource
session_medium, sessionMedium medium sessionMedium
sessionDefaultChannelGroup, session_default_channel_grouping, default_channel_grouping, channel, channel_group session_default_channel_group sessionDefaultChannelGroup
session_campaign_name, sessionCampaignName, session_campaign campaign or campaign_name sessionCampaignName
sessionSourceMedium session_source_medium sessionSourceMedium
screenPageViews, pageviews, page_views, views screen_page_views screenPageViews
eventCount, total_events event_count eventCount
eventName event_name eventName
total_revenue, revenue totalrevenue (or transactionrevenue) totalRevenue
purchaseRevenue purchase_revenue purchaseRevenue
engagementRate engagement_rate engagementRate
engagedSessions engaged_sessions engagedSessions
averageSessionDuration, avg_session_duration average_session_duration averageSessionDuration
bounceRate bounce_rate bounceRate
activeUsers active_users or users activeUsers
key_events, keyEvents, conversions_generate_lead and other conversions_<event> names conversions, with event_name and a filter on the event keyEvents
conversion_rate session_conversion_rate or user_conversion_rate sessionKeyEventRate, userKeyEventRate
addToCarts add_to_carts addToCarts
ecommercePurchases, purchases ecommerce_purchases (event level) or items_purchased (per item) ecommercePurchases, itemsPurchased
landingPage landing_page landingPage
pagePath page_path pagePath
page_title, pageTitle pagetitle pageTitle
itemName, itemRevenue, itemsPurchased, itemsViewed, itemsAddedToCart item_name, item_revenue, items_purchased, items_viewed, items_added_to_cart same names in camelCase
item_views items_viewed (per item) or item_view_events (event level) itemsViewed, itemViewEvents
transaction_id, transactionId transactionid transactionId
yearMonth year_month yearMonth
accountname, accountid, property_id, property_name account_name and account_id exist; the others do not. See the note below none

Rule of thumb when a name is not in this table: write Google’s API name in snake_case, then check it against the field reference. If it is still rejected, search the reference for the label you see in the GA4 interface.

Custom dimensions, custom metrics and custom channel groups are exposed, but only in the field list for your own account, and under generated IDs rather than the names you gave them: customevent_<parameter> for event-scoped custom dimensions, customuser_<parameter> for user-scoped ones, countcustomevent_ and averagecustomevent_ variants for custom metrics, and sessioncustomchannelgroup_<id> or customchannelgroup_<id> for custom channel groups. Call get_fields for your account, or open the field list in the Windsor app, to see the exact IDs. Parameter names that contain characters other than letters, numbers and underscores cannot be requested; that is the “GA4 API allows requesting only metrics which include letters, numbers, or _” error.

account_name and account_id on GA4: “Did you mean adSourceName?”

A related error reads “Did you mean adSourceName? Field account_name is not a valid dimension” or “Did you mean country? Field account_id is not a valid dimension”, followed by “This field might not exist for the [property] account”. Here the names exist in Windsor’s list and work on most properties, but on some the request is passed on to Google with the field included, and Google answers with its nearest guess. The suggestion (adSourceName, country) is unrelated to what you wanted, so ignore it.

  • Fix: drop account_name and account_id from that request. To limit a request to one property, pass its ID in the accounts parameter (the MCP tool and the API both have it) instead of selecting an account field.
  • Ask your assistant: “Drop account_name and account_id from the GA4 field list and restrict the request to property [ID] with the accounts parameter.”

General troubleshooting checklist

  1. Copy every name inside the braces of the error. All of them must change; fixing one and retrying only surfaces the next.
  2. Look each one up in the table above, or in the field reference. In Claude or ChatGPT, ask the assistant to call get_fields for googleanalytics4 and pick from that list.
  3. Watch the five lowercase legacy IDs: totalusers, newusers, totalrevenue, pagetitle, transactionid. Snake_case versions of these do not exist.
  4. Remember the renamed ones: conversions for key events, source and medium for session source and medium, campaign for session campaign name.
  5. Do not request per-event key-event metrics (conversions_purchase, conversions_form_submit). Use conversions with event_name and filter on the event.
  6. Once every name is valid, the request may still fail on scope. That is a different error, covered in the GA4 “Fields cannot be queried together” guide.

Still stuck?

If a field you can see in the GA4 interface has no equivalent in the field reference or in get_fields for your account, reach out to support with:

  • The label as shown in GA4 and, if you know it, the API name from the GA4 Dimensions & Metrics Explorer.
  • Whether it is a standard field or a custom dimension, metric or channel group you created, and the parameter name behind it.
  • The report you are trying to build.

Missing standard fields get added to the connector.

Related reading

Tired of juggling fragmented data? Get started with Windsor.ai today to create a single source of truth

Let us help you streamline data integration and AI insights, so you can focus on what matters: growth strategy.
g logo
fb logo
big query data
youtube logo
power logo
looker logo