Connect Google Ads to Lovable
Automatically sync your Google Ads data to Lovable using the Windsor.ai connector.
Talk to your Google Ads data in Lovable, build a custom PPC analytics app, and get AI-driven insights to optimize campaigns, cut wasted spend, and improve ROAS.
Forget CSVs. Stop copy/paste. Connect data in minutes. No code required.
Optimize your Google Ads performance with AI-Powered analysis in Lovable
Windsor MCP syncs your Google Ads data into Lovable automatically, so you spend less time pulling reports and more time making decisions that improve performance. Discover key use cases:
Cut wasted spend
Some keywords consume budget without ever converting. Lovable surfaces them ranked by spend, filtered by zero conversions, and grouped by campaign, so you can pause or add negatives before another week of budget disappears.
Find winning search terms
Lovable scans your search terms report and surfaces high-converting queries you haven’t added as keywords yet. This helps you expand reach, lower CPA, and capture that traffic before your competitors do.
Compare campaign type ROAS
Compare ROAS across Search, Shopping, Performance Max, and Demand Gen. Lovable breaks down spend, conversion value, and ROAS per campaign type in a single view, making it easy to see where your budget is working hardest and where reallocation would move the needle.
Uncover true conversion attribution
Connect Google Ads with GA4 through Windsor MCP to map the full journey, from ad click to on-site behavior. Lovable highlights which campaigns drive real engagement and which inflate conversion numbers without delivering actual value.
Build live Google Ads client reports
Use Lovable to generate a live paid search report your client can open anytime: spend by campaign, ROAS, CPA, or wasted budget. Just share a URL your team can open in any browser, no login needed from their end.
Using Windsor.ai to connect data from Google Ads to Lovable
Getting Google Ads data into Lovable usually requires manual exports, tedious data prep, or costly tools. Windsor MCP removes these barriers by automatically pulling, normalizing, and syncing your campaigns, keywords, ad groups, and conversion metrics into Lovable.
Analyze your Google Ads data using natural language prompts and build performance dashboards in seconds.
Available actions
Push Negative Keywords Add negative keywords to a Google Ads campaign or ad group. Set level to 'campaign' (with campaign_id) to block the terms across the whole campaign, or 'ad_group' (with ad_group_id) to block them only in that ad group. Each keyword has a match type (BROAD, PHRASE or EXACT, defaulting to BROAD). Keywords are pushed in one request; any that Google rejects (for example a duplicate, or a negative that already exists on the target) are skipped and reported, and the remaining valid keywords are still added. To read back the pushed negative keywords, query get_data with the campaign_criterion_keyword_text, campaign_criterion_keyword_match_type and campaign_criterion_negative fields (campaign level) or the ad_group_criterion_keyword_text, ad_group_criterion_keyword_match_type and ad_group_criterion_negative fields (ad group level).
Add negative keywords to a Google Ads campaign or ad group. Set level to 'campaign' (with campaign_id) to block the terms across the whole campaign, or 'ad_group' (with ad_group_id) to block them only in that ad group. Each keyword has a match type (BROAD, PHRASE or EXACT, defaulting to BROAD). Keywords are pushed in one request; any that Google rejects (for example a duplicate, or a negative that already exists on the target) are skipped and reported, and the remaining valid keywords are still added. To read back the pushed negative keywords, query get_data with the campaign_criterion_keyword_text, campaign_criterion_keyword_match_type and campaign_criterion_negative fields (campaign level) or the ad_group_criterion_keyword_text, ad_group_criterion_keyword_match_type and ad_group_criterion_negative fields (ad group level).
Push Keywords Add positive keywords to a Google Ads ad group (positive keywords live on the ad group, not the campaign). Each keyword has a match type (BROAD, PHRASE or EXACT, defaulting to BROAD) and an optional max CPC bid in micros. Status ('enabled' or 'paused') defaults to 'enabled' for the whole batch and can be overridden per keyword. Keywords are pushed in one request; any that Google rejects (for example a duplicate that already exists in the ad group) are skipped and reported, and the remaining valid keywords are still added.
Add positive keywords to a Google Ads ad group (positive keywords live on the ad group, not the campaign). Each keyword has a match type (BROAD, PHRASE or EXACT, defaulting to BROAD) and an optional max CPC bid in micros. Status ('enabled' or 'paused') defaults to 'enabled' for the whole batch and can be overridden per keyword. Keywords are pushed in one request; any that Google rejects (for example a duplicate that already exists in the ad group) are skipped and reported, and the remaining valid keywords are still added.
Create Responsive Search Ad Create a responsive search ad inside an existing Search ad group. Provide 3-15 headlines (max 30 characters each) and 2-4 descriptions (max 90 characters each); Google mixes them into ad combinations. final_url is the landing page. The optional path1 and path2 are display-URL segments (max 15 characters each; path2 requires path1). The ad is created paused by default so it does not start serving immediately.
Create a responsive search ad inside an existing Search ad group. Provide 3-15 headlines (max 30 characters each) and 2-4 descriptions (max 90 characters each); Google mixes them into ad combinations. final_url is the landing page. The optional path1 and path2 are display-URL segments (max 15 characters each; path2 requires path1). The ad is created paused by default so it does not start serving immediately.
Create Ad Group Create a new ad group inside an existing Search or Display campaign. The ad group type is derived from the campaign's channel type. The optional cpc_bid_micros sets the default max CPC bid in micros of the account currency (1,000,000 micros = 1 unit). The ad group is created paused by default.
Create a new ad group inside an existing Search or Display campaign. The ad group type is derived from the campaign's channel type. The optional cpc_bid_micros sets the default max CPC bid in micros of the account currency (1,000,000 micros = 1 unit). The ad group is created paused by default.
Create Campaign Create a new Search or Display Google Ads campaign together with its daily budget in a single atomic request. The budget amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 50_000_000 means 50.00). The campaign is created paused by default so it does not start serving immediately. It is declared as not containing EU political advertising unless contains_eu_political_advertising is set to true. The maximize_conversions bidding strategy requires conversion tracking to be enabled on the account. Add ad groups to it with the create_ad_group action.
Create a new Search or Display Google Ads campaign together with its daily budget in a single atomic request. The budget amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 50_000_000 means 50.00). The campaign is created paused by default so it does not start serving immediately. It is declared as not containing EU political advertising unless contains_eu_political_advertising is set to true. The maximize_conversions bidding strategy requires conversion tracking to be enabled on the account. Add ad groups to it with the create_ad_group action.
Set Campaign Budget Set the daily or total (lifetime) budget of a Google Ads campaign. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 50_000_000 means 50.00). A lifetime budget only applies to campaigns with a fixed end date. If the budget is also used by other campaigns, the change is rejected unless apply_to_shared_budget is set to true, because it would affect every campaign that shares that budget.
Set the daily or total (lifetime) budget of a Google Ads campaign. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 50_000_000 means 50.00). A lifetime budget only applies to campaigns with a fixed end date. If the budget is also used by other campaigns, the change is rejected unless apply_to_shared_budget is set to true, because it would affect every campaign that shares that budget.
Create Ad Asset Create a Google Ads ad extension asset and link it to a campaign or ad group in one atomic request. Supported asset_type values: 'sitelink' (extra links under the ad; needs link_text and final_url, with optional description_1 and description_2), 'callout' (short non-clickable highlight; needs callout_text), 'structured_snippet' (a header plus 3-10 values; needs header and values) and 'call' (a phone number; needs phone_number and country_code). Set level to 'campaign' (with campaign_id) to apply the extension across the whole campaign, or 'ad_group' (with ad_group_id) to apply it to one ad group only. Each call creates one asset; call the action again for each additional extension. New call and sitelink assets go through Google's policy review before they start showing.
Create a Google Ads ad extension asset and link it to a campaign or ad group in one atomic request. Supported asset_type values: 'sitelink' (extra links under the ad; needs link_text and final_url, with optional description_1 and description_2), 'callout' (short non-clickable highlight; needs callout_text), 'structured_snippet' (a header plus 3-10 values; needs header and values) and 'call' (a phone number; needs phone_number and country_code). Set level to 'campaign' (with campaign_id) to apply the extension across the whole campaign, or 'ad_group' (with ad_group_id) to apply it to one ad group only. Each call creates one asset; call the action again for each additional extension. New call and sitelink assets go through Google's policy review before they start showing.
Enable Campaign Enable a paused Google Ads campaign. Reversible via pause_campaign.
Enable a paused Google Ads campaign. Reversible via pause_campaign.
Pause Campaign Pause an active Google Ads campaign. Reversible via enable_campaign.
Pause an active Google Ads campaign. Reversible via enable_campaign.
Enable Ad Enable a paused ad within an ad group. Identify the ad by its ad group id and ad id; the create ad actions return these joined as '<ad_group_id>~<ad_id>'. Reversible via pause_ad.
Enable a paused ad within an ad group. Identify the ad by its ad group id and ad id; the create ad actions return these joined as '<ad_group_id>~<ad_id>'. Reversible via pause_ad.
Pause Ad Pause an active ad within an ad group. Identify the ad by its ad group id and ad id; the create ad actions return these joined as '<ad_group_id>~<ad_id>'. Reversible via enable_ad.
Pause an active ad within an ad group. Identify the ad by its ad group id and ad id; the create ad actions return these joined as '<ad_group_id>~<ad_id>'. Reversible via enable_ad.
Update Keywords Update existing positive keywords in a Google Ads ad group, identified by ad group criterion id (from the get_data 'keyword_criterion_id' field). Each update can change the keyword's status ('enabled' or 'paused') and/or its max CPC bid in micros; a keyword's text and match type cannot be changed (remove and re-add to change those). Updates are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid updates are still applied.
Update existing positive keywords in a Google Ads ad group, identified by ad group criterion id (from the get_data 'keyword_criterion_id' field). Each update can change the keyword's status ('enabled' or 'paused') and/or its max CPC bid in micros; a keyword's text and match type cannot be changed (remove and re-add to change those). Updates are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid updates are still applied.
Enable Ad Group Enable a paused Google Ads ad group. Reversible via pause_ad_group.
Enable a paused Google Ads ad group. Reversible via pause_ad_group.
Set Campaign Bidding Strategy Switch a Google Ads campaign to a different standard (campaign-level) bidding strategy. Supported strategies: manual_cpc, target_cpa, target_roas, maximize_conversions, maximize_conversion_value, maximize_clicks, target_spend. maximize_clicks and target_spend are aliases for the same strategy (the former is the Google Ads UI label, the latter the API and get_data field naming). target_cpa_micros is required for target_cpa and maximize_conversions (1,000,000 micros = 1 unit of the account currency). target_roas is required for target_roas and maximize_conversion_value (expressed as a ratio, e.g. 4.0 means 400% return on ad spend). cpc_bid_ceiling_micros is required for maximize_clicks and target_spend; it is not accepted for other strategies because the API only allows a campaign-level ceiling on Target Spend (other strategies require a portfolio bidding strategy). manual_cpc takes no additional parameters.
Switch a Google Ads campaign to a different standard (campaign-level) bidding strategy. Supported strategies: manual_cpc, target_cpa, target_roas, maximize_conversions, maximize_conversion_value, maximize_clicks, target_spend. maximize_clicks and target_spend are aliases for the same strategy (the former is the Google Ads UI label, the latter the API and get_data field naming). target_cpa_micros is required for target_cpa and maximize_conversions (1,000,000 micros = 1 unit of the account currency). target_roas is required for target_roas and maximize_conversion_value (expressed as a ratio, e.g. 4.0 means 400% return on ad spend). cpc_bid_ceiling_micros is required for maximize_clicks and target_spend; it is not accepted for other strategies because the API only allows a campaign-level ceiling on Target Spend (other strategies require a portfolio bidding strategy). manual_cpc takes no additional parameters.
Set CPC Bid Ceiling Set the maximum CPC bid the strategy is allowed to place on a Google Ads campaign. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50). Only applies to campaigns using Target Spend / Maximize Clicks bidding. Other strategies (Target CPA, Target ROAS, Maximize Conversions, Maximize Conversion Value) treat ceiling as portfolio-only per the Google Ads API, so those cannot be adjusted via this action.
Set the maximum CPC bid the strategy is allowed to place on a Google Ads campaign. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50). Only applies to campaigns using Target Spend / Maximize Clicks bidding. Other strategies (Target CPA, Target ROAS, Maximize Conversions, Maximize Conversion Value) treat ceiling as portfolio-only per the Google Ads API, so those cannot be adjusted via this action.
Remove Keywords Remove positive keywords from a Google Ads ad group, identified by ad group criterion id (from the get_data 'keyword_criterion_id' field). Removals are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid removals still apply.
Remove positive keywords from a Google Ads ad group, identified by ad group criterion id (from the get_data 'keyword_criterion_id' field). Removals are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid removals still apply.
Pause Ad Group Pause an active Google Ads ad group. Reversible via enable_ad_group.
Pause an active Google Ads ad group. Reversible via enable_ad_group.
Set Campaign Language Targeting Set the languages a Google Ads campaign targets, so its ads only reach users Google associates with one of them. Each language is given as its Google Ads language code, spelled exactly as the languages parameter enumerates it (e.g. en, de, es, zh_CN). Regional variants such as en_US and en_GB are not among them and cannot be targeted, only the base en. Google's table of these codes with the language each one names is at https://developers.google.com/google-ads/api/data/codes-formats#languages. This replaces the whole language targeting — every language to target must be listed in one call, because the languages not listed are removed. Languages already targeted are left in place, so their criterion ids do not change. A campaign with no language criteria targets all languages; pass an empty list to clear the targeting and return it to that state. Language targeting cannot be negative: there is no way to exclude a single language, only to list the ones to target. Google rejects the change for campaign types that do not support language criteria (e.g. Smart campaigns).
Set the languages a Google Ads campaign targets, so its ads only reach users Google associates with one of them. Each language is given as its Google Ads language code, spelled exactly as the languages parameter enumerates it (e.g. en, de, es, zh_CN). Regional variants such as en_US and en_GB are not among them and cannot be targeted, only the base en. Google's table of these codes with the language each one names is at https://developers.google.com/google-ads/api/data/codes-formats#languages. This replaces the whole language targeting — every language to target must be listed in one call, because the languages not listed are removed. Languages already targeted are left in place, so their criterion ids do not change. A campaign with no language criteria targets all languages; pass an empty list to clear the targeting and return it to that state. Language targeting cannot be negative: there is no way to exclude a single language, only to list the ones to target. Google rejects the change for campaign types that do not support language criteria (e.g. Smart campaigns).
Remove Negative Keywords Remove negative keywords from a Google Ads campaign or ad group, identified by criterion id. Set level to 'campaign' (with campaign_id) or 'ad_group' (with ad_group_id) to match where the negative keywords are attached. Removals are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid removals still apply. Reversible via push_negative_keywords by re-adding the keyword text and match type.
Remove negative keywords from a Google Ads campaign or ad group, identified by criterion id. Set level to 'campaign' (with campaign_id) or 'ad_group' (with ad_group_id) to match where the negative keywords are attached. Removals are applied in one request; any that Google rejects (for example an unknown criterion id) are skipped and reported, and the remaining valid removals still apply. Reversible via push_negative_keywords by re-adding the keyword text and match type.
Set Max CPC Bid Set the default Max CPC bid on a Google Ads ad group. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50). Manual CPC bids live on the ad group, not the campaign, so the parent campaign must use the Manual CPC bidding strategy; switch it first via set_campaign_bidding_strategy if it uses Smart Bidding.
Set the default Max CPC bid on a Google Ads ad group. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50). Manual CPC bids live on the ad group, not the campaign, so the parent campaign must use the Manual CPC bidding strategy; switch it first via set_campaign_bidding_strategy if it uses Smart Bidding.
Set Ad Schedule Set the ad schedule (dayparting) of a Google Ads campaign: the days and times of day its ads are allowed to serve, each with an optional bid adjustment. This replaces the campaign's whole schedule — every window it should serve in must be listed in one call, because the windows not listed are removed. Times are in the campaign's account time zone. Hours are 24-hour, minutes are limited to 0, 15, 30 and 45, and each window is exclusive of its end time, so 09:00-17:00 serves up to but not including 17:00; use end_hour 24 for the end of the day. Windows for the same day must not overlap, and a day takes at most six of them. A campaign with no ad schedule serves at all times; pass an empty schedule list to clear the schedule and return it to that state. To read the current schedule, query get_data with the campaign_criterion_ad_schedule_day_of_week, campaign_criterion_ad_schedule_start_hour, campaign_criterion_ad_schedule_start_minute, campaign_criterion_ad_schedule_end_hour and campaign_criterion_ad_schedule_end_minute fields.
Set the ad schedule (dayparting) of a Google Ads campaign: the days and times of day its ads are allowed to serve, each with an optional bid adjustment. This replaces the campaign's whole schedule — every window it should serve in must be listed in one call, because the windows not listed are removed. Times are in the campaign's account time zone. Hours are 24-hour, minutes are limited to 0, 15, 30 and 45, and each window is exclusive of its end time, so 09:00-17:00 serves up to but not including 17:00; use end_hour 24 for the end of the day. Windows for the same day must not overlap, and a day takes at most six of them. A campaign with no ad schedule serves at all times; pass an empty schedule list to clear the schedule and return it to that state. To read the current schedule, query get_data with the campaign_criterion_ad_schedule_day_of_week, campaign_criterion_ad_schedule_start_hour, campaign_criterion_ad_schedule_start_minute, campaign_criterion_ad_schedule_end_hour and campaign_criterion_ad_schedule_end_minute fields.
Set Target CPA Set the target cost per acquisition on a Google Ads campaign already using Target CPA or Maximize Conversions bidding. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 25_000_000 means 25.00). To switch a campaign to Target CPA bidding, use set_campaign_bidding_strategy with strategy='target_cpa' instead.
Set the target cost per acquisition on a Google Ads campaign already using Target CPA or Maximize Conversions bidding. The amount is in micros of the account currency (1,000,000 micros = 1 unit, e.g. 25_000_000 means 25.00). To switch a campaign to Target CPA bidding, use set_campaign_bidding_strategy with strategy='target_cpa' instead.
Rename Campaign Change the name of an existing Google Ads campaign. Only the name changes: budget, bidding, targeting, status, ad groups and ads are all left as they are, and historical reporting stays attached to the campaign because reports key on the campaign id. Campaign names must be unique within the account, so renaming to a name another campaign already uses is rejected. To rename an ad group instead, use the rename_ad_group action.
Change the name of an existing Google Ads campaign. Only the name changes: budget, bidding, targeting, status, ad groups and ads are all left as they are, and historical reporting stays attached to the campaign because reports key on the campaign id. Campaign names must be unique within the account, so renaming to a name another campaign already uses is rejected. To rename an ad group instead, use the rename_ad_group action.
Rename Ad Group Change the name of an existing Google Ads ad group. Only the name changes: bids, targeting, status, keywords and ads are all left as they are, and historical reporting stays attached to the ad group because reports key on the ad group id. Ad group names must be unique within their campaign, so renaming to a name another ad group in the same campaign already uses is rejected. To rename a campaign instead, use the rename_campaign action.
Change the name of an existing Google Ads ad group. Only the name changes: bids, targeting, status, keywords and ads are all left as they are, and historical reporting stays attached to the ad group because reports key on the ad group id. Ad group names must be unique within their campaign, so renaming to a name another ad group in the same campaign already uses is rejected. To rename a campaign instead, use the rename_campaign action.
Set Target ROAS Set the target return on ad spend on a Google Ads campaign already using Target ROAS or Maximize Conversion Value bidding. The value is a ratio of conversion value to spend, not a percentage (e.g. 4.0 means 400% ROAS). To switch a campaign to Target ROAS bidding, use set_campaign_bidding_strategy with strategy='target_roas' instead.
Set the target return on ad spend on a Google Ads campaign already using Target ROAS or Maximize Conversion Value bidding. The value is a ratio of conversion value to spend, not a percentage (e.g. 4.0 means 400% ROAS). To switch a campaign to Target ROAS bidding, use set_campaign_bidding_strategy with strategy='target_roas' instead.
Create Customer Match List Create an empty Google Ads Customer Match user list (CRM-based, with CONTACT_INFO as the upload key type — email, phone, or mailing address) that can then be populated with upload_customer_match_list. Returns the numeric user_list_id to pass to that action. membership_life_span_days controls how long an uploaded member remains in the list before Google auto-removes it: 1-540 for a fixed lifespan, or 10000 as Google's sentinel value for 'no expiration'. The account must be enrolled in Customer Match; if it is not, creation fails with a policy error and no list is created.
Create an empty Google Ads Customer Match user list (CRM-based, with CONTACT_INFO as the upload key type — email, phone, or mailing address) that can then be populated with upload_customer_match_list. Returns the numeric user_list_id to pass to that action. membership_life_span_days controls how long an uploaded member remains in the list before Google auto-removes it: 1-540 for a fixed lifespan, or 10000 as Google's sentinel value for 'no expiration'. The account must be enrolled in Customer Match; if it is not, creation fails with a policy error and no list is created.
Attach User List to Ad Group Attach a Customer Match user list to a Google Ads ad group so the ad group can target or exclude users in that list. Pass exclude=false (default) to add the list as a positive audience criterion, or exclude=true to add it as a negative criterion (never show ads to users in the list — commonly used to suppress existing customers). This action is idempotent: attaching a list that is already attached with the same exclude value is a no-op and returns the existing criterion. Attaching with a different exclude value than the current attachment returns an error — detach first, then re-attach. targeting_mode controls whether the list narrows delivery for the ad group ('targeting') or is only used for reporting and bidding ('observation'). Passing 'targeting' or 'observation' updates the ad group's AUDIENCE target_restriction; other target_restrictions (e.g. DEMOGRAPHIC) are preserved. Passing 'unchanged' (default) leaves targeting_setting untouched; note the setting is ad-group-wide, so changing it affects ALL audience criteria on the ad group, not just the list being attached. Negative (exclude=true) criteria always apply regardless of targeting_setting. Scope: this action is for AD-GROUP-level audiences only; campaign-level audience criteria and Performance Max audience signals use different APIs and are not supported here.
Attach a Customer Match user list to a Google Ads ad group so the ad group can target or exclude users in that list. Pass exclude=false (default) to add the list as a positive audience criterion, or exclude=true to add it as a negative criterion (never show ads to users in the list — commonly used to suppress existing customers). This action is idempotent: attaching a list that is already attached with the same exclude value is a no-op and returns the existing criterion. Attaching with a different exclude value than the current attachment returns an error — detach first, then re-attach. targeting_mode controls whether the list narrows delivery for the ad group ('targeting') or is only used for reporting and bidding ('observation'). Passing 'targeting' or 'observation' updates the ad group's AUDIENCE target_restriction; other target_restrictions (e.g. DEMOGRAPHIC) are preserved. Passing 'unchanged' (default) leaves targeting_setting untouched; note the setting is ad-group-wide, so changing it affects ALL audience criteria on the ad group, not just the list being attached. Negative (exclude=true) criteria always apply regardless of targeting_setting. Scope: this action is for AD-GROUP-level audiences only; campaign-level audience criteria and Performance Max audience signals use different APIs and are not supported here.
Upload Customer Match List Upload contact records (email, phone, or mailing address) to a Google Ads Customer Match user list for audience targeting. The user list must already exist in Google Ads; pass its numeric id as user_list_id. If you do not have one yet, call create_customer_match_list first to create an empty list and get its id. Uploads go through Google's Data Manager API (https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match), which requires the Google Ads account to have been authorised with the ``https://www.googleapis.com/auth/datamanager`` OAuth scope; the action returns a clear error if the scope is missing. This action is ASYNCHRONOUS: it returns immediately with a request_id once Google has accepted the request. Google then matches the records against signed-in users in the background — this typically takes a few minutes but can take up to 24 hours for large lists. The user list is NOT usable for targeting until matching completes. To check progress, call get_customer_match_upload_status with the returned request_id. Poll no more than once every 60 seconds. The job is done when status is SUCCESS, PARTIAL_SUCCESS, or FAILED; while it is PROCESSING keep polling. PII HANDLING: emails, phone numbers, and names are normalized and SHA-256 hashed by this action before being sent to Google — do NOT pre-hash them; pass raw values. operation_type=add appends records to the list; operation_type=remove removes matching records (use for compliance requests such as GDPR erasure). At most 10,000 records per call; split larger uploads into multiple calls.
Upload contact records (email, phone, or mailing address) to a Google Ads Customer Match user list for audience targeting. The user list must already exist in Google Ads; pass its numeric id as user_list_id. If you do not have one yet, call create_customer_match_list first to create an empty list and get its id. Uploads go through Google's Data Manager API (https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match), which requires the Google Ads account to have been authorised with the ``https://www.googleapis.com/auth/datamanager`` OAuth scope; the action returns a clear error if the scope is missing. This action is ASYNCHRONOUS: it returns immediately with a request_id once Google has accepted the request. Google then matches the records against signed-in users in the background — this typically takes a few minutes but can take up to 24 hours for large lists. The user list is NOT usable for targeting until matching completes. To check progress, call get_customer_match_upload_status with the returned request_id. Poll no more than once every 60 seconds. The job is done when status is SUCCESS, PARTIAL_SUCCESS, or FAILED; while it is PROCESSING keep polling. PII HANDLING: emails, phone numbers, and names are normalized and SHA-256 hashed by this action before being sent to Google — do NOT pre-hash them; pass raw values. operation_type=add appends records to the list; operation_type=remove removes matching records (use for compliance requests such as GDPR erasure). At most 10,000 records per call; split larger uploads into multiple calls.
Delete Customer Match List Permanently delete a Google Ads Customer Match user list. Detaches the list from any ad groups or campaigns currently using it as an audience or exclusion criterion and removes all uploaded members. Historical performance data for the list is retained in reports. Cannot be undone; to recover, create a new list and re-upload members. Use with care — deleting a list that is actively targeting a live campaign changes delivery immediately.
Permanently delete a Google Ads Customer Match user list. Detaches the list from any ad groups or campaigns currently using it as an audience or exclusion criterion and removes all uploaded members. Historical performance data for the list is retained in reports. Cannot be undone; to recover, create a new list and re-upload members. Use with care — deleting a list that is actively targeting a live campaign changes delivery immediately.
Detach User List from Ad Group Remove a Customer Match user list criterion (audience or exclusion) from a Google Ads ad group. Reverses attach_user_list_to_ad_group. Removes both positive (audience) and negative (exclusion) criteria — pass the same ad_group_id and user_list_id used when attaching. Removing a user list stops any targeting or reporting effect it had on future traffic; historical performance data remains in reports. If the list is not currently attached to the ad group, the action returns an error and no changes are made.
Remove a Customer Match user list criterion (audience or exclusion) from a Google Ads ad group. Reverses attach_user_list_to_ad_group. Removes both positive (audience) and negative (exclusion) criteria — pass the same ad_group_id and user_list_id used when attaching. Removing a user list stops any targeting or reporting effect it had on future traffic; historical performance data remains in reports. If the list is not currently attached to the ad group, the action returns an error and no changes are made.
Get Customer Match Upload Status Check the status of a Customer Match upload request started by upload_customer_match_list. Pass the request_id that action returned. Status is one of PROCESSING, SUCCESS, PARTIAL_SUCCESS, FAILED. PROCESSING means matching is still in progress — poll again in at least 60 seconds. Do NOT poll more frequently; quota is shared with data reads. If still PROCESSING after 24 hours, treat as stuck and contact support. SUCCESS means every uploaded record was accepted; the response includes the record count and match_rate_range, a coarse bucket indicating what fraction of uploaded records were matched to signed-in Google users. A low match rate usually reflects source data quality (invalid or non-Google-account emails/phones), not upload failure. For operation_type=remove requests, SUCCESS means the matching records were removed from the list. PARTIAL_SUCCESS means some records were accepted and others were rejected; the response includes the same counts plus the error message describing which records failed. The list still receives the accepted records. FAILED means the entire request failed with no records ingested; the response includes the reason. Failed requests cannot be resumed; start a new upload after fixing the issue.
Check the status of a Customer Match upload request started by upload_customer_match_list. Pass the request_id that action returned. Status is one of PROCESSING, SUCCESS, PARTIAL_SUCCESS, FAILED. PROCESSING means matching is still in progress — poll again in at least 60 seconds. Do NOT poll more frequently; quota is shared with data reads. If still PROCESSING after 24 hours, treat as stuck and contact support. SUCCESS means every uploaded record was accepted; the response includes the record count and match_rate_range, a coarse bucket indicating what fraction of uploaded records were matched to signed-in Google users. A low match rate usually reflects source data quality (invalid or non-Google-account emails/phones), not upload failure. For operation_type=remove requests, SUCCESS means the matching records were removed from the list. PARTIAL_SUCCESS means some records were accepted and others were rejected; the response includes the same counts plus the error message describing which records failed. The list still receives the accepted records. FAILED means the entire request failed with no records ingested; the response includes the reason. Failed requests cannot be resumed; start a new upload after fixing the issue.
Update Ad Group Partially update an existing Google Ads ad group. Provide only the fields to change; at least one besides ad_group_id is required and omitted fields are left untouched. status is 'enabled' or 'paused'; ad_rotation_mode is 'optimize' or 'rotate_forever'. cpc_bid_micros is the default max CPC bid in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50) and only applies when the parent campaign uses Manual CPC; switch it first via set_campaign_bidding_strategy if it uses Smart Bidding. Budget, target CPA and CPM bids are not editable here. This is a value change with no built-in undo: to reverse it read the current values first (e.g. GAQL 'SELECT ad_group.name, ad_group.status, ad_group.cpc_bid_micros, ad_group.ad_rotation_mode FROM ad_group WHERE ad_group.id = <id>') then call update_ad_group again with the previous values. The single-purpose rename_ad_group, pause_ad_group/enable_ad_group and set_max_cpc actions still exist; prefer them for one change and use update_ad_group to change several fields at once.
Partially update an existing Google Ads ad group. Provide only the fields to change; at least one besides ad_group_id is required and omitted fields are left untouched. status is 'enabled' or 'paused'; ad_rotation_mode is 'optimize' or 'rotate_forever'. cpc_bid_micros is the default max CPC bid in micros of the account currency (1,000,000 micros = 1 unit, e.g. 2_500_000 means 2.50) and only applies when the parent campaign uses Manual CPC; switch it first via set_campaign_bidding_strategy if it uses Smart Bidding. Budget, target CPA and CPM bids are not editable here. This is a value change with no built-in undo: to reverse it read the current values first (e.g. GAQL 'SELECT ad_group.name, ad_group.status, ad_group.cpc_bid_micros, ad_group.ad_rotation_mode FROM ad_group WHERE ad_group.id = <id>') then call update_ad_group again with the previous values. The single-purpose rename_ad_group, pause_ad_group/enable_ad_group and set_max_cpc actions still exist; prefer them for one change and use update_ad_group to change several fields at once.
Rename Customer Match List Change the display name of a Google Ads Customer Match user list. Does not affect membership, campaign attachments, targeting behaviour, or the list's configuration — only the name shown in the Google Ads UI and reports. Names must be unique per account; Google returns an error if another list already uses the requested name.
Change the display name of a Google Ads Customer Match user list. Does not affect membership, campaign attachments, targeting behaviour, or the list's configuration — only the name shown in the Google Ads UI and reports. Names must be unique per account; Google returns an error if another list already uses the requested name.
Set Campaign Geo Targeting Set the geographic targeting of a Google Ads campaign: the countries, regions or cities its ads may serve in, plus optional radius (proximity) areas. Give the complete set of locations to target or exclude in one call; a location currently targeted but left out of the call is removed, and each location may be listed only once. Locations are identified by their numeric geo target constant id (e.g. 2840 for the United States); set a location's 'negative' flag to exclude it (for example target a country but exclude a state), and give targeted locations or proximities an optional bid_modifier between 0.1 and 10.0 (1.0 leaves bids unchanged; excluded locations may not have one). Re-running keeps the locations that stay in the set and updates their bid modifier, but a location cannot be switched between targeted and excluded in one call: omit it to remove it, then add it back the other way in a later call. A proximity area is a point (latitude, longitude) and a radius in miles or kilometers; proximity areas can only be targeted, not excluded, and are replaced as a whole on each call. Passing empty location and proximity lists clears the campaign's geo targeting so its ads can serve in all locations. To read the current geo targeting, query get_data with the criteria_type, campaign_criterion_location_geo_target_constant, campaign_criterion_negative, campaign_criterion_bid_modifier, campaign_criterion_proximity_geo_point_latitude_in_micro_degrees, campaign_criterion_proximity_geo_point_longitude_in_micro_degrees, campaign_criterion_proximity_radius and campaign_criterion_proximity_radius_units fields.
Set the geographic targeting of a Google Ads campaign: the countries, regions or cities its ads may serve in, plus optional radius (proximity) areas. Give the complete set of locations to target or exclude in one call; a location currently targeted but left out of the call is removed, and each location may be listed only once. Locations are identified by their numeric geo target constant id (e.g. 2840 for the United States); set a location's 'negative' flag to exclude it (for example target a country but exclude a state), and give targeted locations or proximities an optional bid_modifier between 0.1 and 10.0 (1.0 leaves bids unchanged; excluded locations may not have one). Re-running keeps the locations that stay in the set and updates their bid modifier, but a location cannot be switched between targeted and excluded in one call: omit it to remove it, then add it back the other way in a later call. A proximity area is a point (latitude, longitude) and a radius in miles or kilometers; proximity areas can only be targeted, not excluded, and are replaced as a whole on each call. Passing empty location and proximity lists clears the campaign's geo targeting so its ads can serve in all locations. To read the current geo targeting, query get_data with the criteria_type, campaign_criterion_location_geo_target_constant, campaign_criterion_negative, campaign_criterion_bid_modifier, campaign_criterion_proximity_geo_point_latitude_in_micro_degrees, campaign_criterion_proximity_geo_point_longitude_in_micro_degrees, campaign_criterion_proximity_radius and campaign_criterion_proximity_radius_units fields.
How to connect Google Ads to Lovable with Windsor.ai
Explore our video tutorial and a step-by-step guide to integrate your Google Ads data into Lovable with the Windsor.ai connector.
Select custom connector in Lovable
In Lovable, open Connectors and select Custom MCP.
Add MCP server
Enter the following details:
- Name: Windsor.ai
- URL: https://mcp.windsor.ai/
Click Add & Authorize to save the connector and authorize access to Windsor.ai.
Authorize and start querying your data
Once added, Windsor will appear in your list of connectors. Enable Always allow permissions for faster access.
Open a new chat and start querying your connected data.
FAQs
What can I do with Google Ads data in Lovable?
Once your Google Ads data is in Lovable, you can:
- Track revenue and ROAS by campaign: Analyze conversion value, ROAS, and cost-per-conversion across all active campaigns, broken down by day, week, or custom date range.
- Monitor CPA and budget efficiency: Identify campaigns and ad groups where cost-per-conversion is above target before it drains your budget.
- Analyze keyword performance: See which keywords drive the most conversions and which are consuming budget without results.
- Diagnose Quality Score issues: Surface low Quality Score keywords alongside their landing page score, expected CTR, and ad relevance to prioritize fixes.
- Track Search Impression Share: See where you’re losing share to budget or rank, and quantify the revenue opportunity.
- Review search terms: Identify high-converting search terms not yet added as keywords, and flag irrelevant queries for negative keyword lists.
- Analyze device performance: Compare CPA, ROAS, and conversion rate across desktop, mobile, and tablet to adjust bid modifiers.
- Build live campaign dashboards: Turn your Google Ads data into shareable Lovable dashboards for clients, leadership, or your media team, updated automatically.
Can I analyze Google Shopping campaign performance in Lovable?
Yes. Windsor.ai pulls Shopping campaign data, including revenue, orders, units sold, gross profit, cost of goods sold, gross profit margin, and product-level breakdowns by title, brand, category, and condition. Ask Lovable to rank products by ROAS, flag items with high spend and low margin, or identify your top revenue-driving SKUs.
Can Lovable detect underperforming campaigns before they drain my budget?
Yes. Ask Lovable to scan campaigns where CPA exceeds your target, ROAS falls below threshold, or spend is above a set amount with zero conversions in a given window. It will surface those campaigns ranked by budget impact so you can pause or adjust bids before the damage compounds.
How much does it cost to connect Google Ads to Lovable using Windsor.ai?
Windsor.ai has a free forever plan with 1 data source and 1 account; no credit card required. Paid plans start at $19/month for more sources. Lovable requires a paid plan to use Custom MCP connectors.
Can Lovable help me calculate my true ROAS?
Yes. Windsor.ai supports integration with 350+ data sources. Blend Google Ads with Shopify, GA4, or your CRM to calculate blended ROAS and understand which campaigns truly deliver returns. For example, use prompts like:
Calculate blended ROAS for the last 30 days, combining Google Ads spend with Shopify revenue. Compare it against Google-attributed ROAS per campaign. Show total Google Ads spend vs GA4 revenue for the last 30 days, broken down by campaign.
What prompts can I use to analyze my Google Ads data in Lovable?
Beyond basic performance summaries, you can use more advanced, specific prompts to uncover deeper insights. For example:
-
Identify my worst-performing ad groups for the last 30 days. Define worst as: CPA more than 2x the campaign average, more than $[X] spend, and fewer than [X] conversions. For each, show spend wasted above the target CPA threshold and recommend whether to pause, restructure, or reduce bids.
-
Analyze my search terms report for the last 30 days. Find search terms that triggered my ads, spent more than $[X], and generated zero conversions. Group them by theme and suggest negative keyword additions at the campaign and ad group level.
-
Break down my Quality Score distribution for the last 30 days. Group keywords into buckets: QS 1-3, 4-6, 7-10. For each bucket, show total spend, average CPA, and average CPC. Calculate how much I could save in CPC if all keywords below QS 5 were improved to QS 7+, using the QS-to-CPC relationship.
-
Calculate true blended ROAS for the last 30 days by combining Google Ads spend with actual conversion value. Then compare it to Target ROAS set in each campaign's bidding strategy. Flag campaigns where actual ROAS is more than 25% below target ROAS and show the revenue gap.
-
Analyze video ad performance for the last 30 days. For each video creative, show impressions, TrueView view rate, 25/50/75/100% completion rates, average CPV, and CPA. Identify which videos have strong view rates but weak conversion rates, these likely have strong hooks but weak CTAs.
Do you have helpful links to get started with integrating Google Ads and Lovable using Windsor.ai?
Yes, we have helpful resources to help you get started. You can explore our official documentation and tutorials for seamless Google Ads to Lovable integration with Windsor.ai:
Can I build a custom Google Ads dashboard in Lovable?
Yes. Tell Lovable what you want to track: campaign performance, keyword analysis, ROAS trends, wasted spend, or a monthly performance summary for all essential metrics and KPIs, and it builds a fully interactive app combining all those views in one place. Add filters, date pickers, and charts without writing a single line of code, then share it as a live URL.
Tired of manual Google Ads data exports? Try Windsor.ai today to automate your reporting

