Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with Google Ads

To integrate Google Ads with Lovable, create Supabase Edge Functions that authenticate using a Google Cloud OAuth2 service account and your Google Ads developer token, then query campaign metrics and keyword performance using GAQL (Google Ads Query Language). Store credentials in Cloud Secrets to build ad performance dashboards and campaign management tools in Lovable.

What you'll learn

  • How to apply for a Google Ads developer token and set up OAuth2 authentication for the Google Ads API
  • How to write GAQL (Google Ads Query Language) queries to fetch campaign metrics and keyword performance
  • How to create a Supabase Edge Function that authenticates with Google Ads API and executes GAQL queries
  • How to build campaign performance dashboards in Lovable with charts and metrics from Google Ads data
  • How to handle Google Ads Manager Account (MCC) structures for multi-client reporting
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read75 minutesMarketingMarch 2026RapidDev Engineering Team
TL;DR

To integrate Google Ads with Lovable, create Supabase Edge Functions that authenticate using a Google Cloud OAuth2 service account and your Google Ads developer token, then query campaign metrics and keyword performance using GAQL (Google Ads Query Language). Store credentials in Cloud Secrets to build ad performance dashboards and campaign management tools in Lovable.

Build Google Ads Campaign Dashboards and Management Tools in Lovable

Marketing teams managing Google Ads campaigns spend hours exporting data from Google Ads interface and building manual reports. Building a custom dashboard in Lovable that pulls live campaign data via the Google Ads API gives your team a purpose-built reporting interface tailored to your metrics — without waiting for CSV exports or navigating Google Ads' complex UI.

The Google Ads API is one of the more complex APIs to integrate due to its multi-layered authentication requirements: every API request needs both an OAuth2 access token (proving who you are) and a developer token (proving your application is approved for API access). The developer token requires applying to Google and explaining your use case — the approval process typically takes a few days. Once approved, you can run GAQL queries that look like SQL and fetch any metric available in the Google Ads interface.

GAQL (Google Ads Query Language) is the core skill for this integration. It is a SQL-like language where you SELECT metrics and dimensions FROM a resource like campaign or keyword_view. You can filter by date ranges, campaign status, and any attribute. This guide covers setting up authentication, writing basic GAQL queries for campaign-level performance, and building a dashboard with key metrics: impressions, clicks, cost, and conversions.

Integration method

Edge Function Integration

Google Ads API integration in Lovable uses Supabase Edge Functions that authenticate via Google's OAuth2 with a service account or refresh token, include the required Google Ads developer token, and execute GAQL queries against the Google Ads API REST endpoint. Your developer token, OAuth credentials, and customer ID are stored encrypted in Cloud Secrets and accessed via Deno.env.get(). The Edge Function returns campaign performance data to your React dashboard components.

Prerequisites

  • A Google Ads account with active campaigns (or a test account for development)
  • A Google Ads developer token — apply at Google Ads API Center under Tools → API Center in your Google Ads account
  • A Google Cloud project with the Google Ads API enabled and OAuth2 credentials configured
  • A Lovable project with Lovable Cloud enabled
  • Patience for the developer token approval process which typically takes 1-5 business days and requires explaining your use case to Google

Step-by-step guide

1

Apply for a Google Ads developer token and set up OAuth2

The Google Ads API requires two separate approvals: a developer token and OAuth2 credentials. For the developer token, log in to Google Ads, go to Tools & Settings → Setup → API Center. If you do not see API Center, your account may need to be a Manager Account (MCC) — you can create a free MCC at ads.google.com/home/tools/manager-accounts/. In API Center, click 'Create developer token'. Fill in your company name, purpose (select 'Reporting and analysis' or 'Campaign management' depending on your use case), and agree to the terms. Google will review your application and either approve or request more information, typically within a few business days. You will start with a Test Account level token that only works with test accounts. Apply for Basic Access level which allows production accounts. For OAuth2, go to Google Cloud Console (console.cloud.google.com), create a new project or select an existing one, navigate to APIs & Services → Library, search for 'Google Ads API', and enable it. Then go to APIs & Services → Credentials and create an OAuth 2.0 Client ID. For a server-side application, create credentials for a Web application or create a Service Account. For the most flexible approach, create a Web application OAuth client, generate a refresh token using OAuth Playground, and store both the client credentials and refresh token.

Pro tip: Use Google's OAuth2 Playground at oauth2.googleapis.com/oauth2/v3 to generate a refresh token without writing code. Select the Google Ads API scope and go through the consent flow to get a long-lived refresh token.

Expected result: You have a Google Ads developer token and OAuth2 credentials (client ID, client secret, and refresh token) ready to store in Cloud Secrets.

2

Store Google Ads credentials in Cloud Secrets

In your Lovable project, open the Cloud tab by clicking '+' next to the Preview, then navigate to the Secrets section. Add four secrets for Google Ads authentication. Add GOOGLE_ADS_DEVELOPER_TOKEN with your developer token value — this is the token from Google Ads API Center that starts with a letter and is approximately 20 characters. Add GOOGLE_ADS_CLIENT_ID with your Google OAuth2 client ID from Google Cloud Console (ends in .apps.googleusercontent.com). Add GOOGLE_ADS_CLIENT_SECRET with the corresponding client secret. Add GOOGLE_ADS_REFRESH_TOKEN with the refresh token you generated through OAuth Playground or your own OAuth flow. Finally, add GOOGLE_ADS_CUSTOMER_ID with your 10-digit Google Ads customer ID (shown in the top right of Google Ads interface, formatted as 123-456-7890 — store without hyphens as 1234567890). For Manager Account setups, this is the MCC customer ID. These credentials together allow your Edge Function to obtain access tokens and make authenticated API calls. Lovable's SOC 2 Type II certified Cloud Secrets storage ensures these highly privileged credentials are encrypted at rest and never accessible from client-side code.

Pro tip: If managing multiple Google Ads accounts, store the Manager Account (MCC) customer ID as GOOGLE_ADS_CUSTOMER_ID and pass individual account customer IDs as parameters in API requests.

Expected result: Five secrets — GOOGLE_ADS_DEVELOPER_TOKEN, GOOGLE_ADS_CLIENT_ID, GOOGLE_ADS_CLIENT_SECRET, GOOGLE_ADS_REFRESH_TOKEN, GOOGLE_ADS_CUSTOMER_ID — are stored in Cloud Secrets.

3

Create the Google Ads API Edge Function with OAuth2 token refresh

Ask Lovable to create a Supabase Edge Function that handles the Google Ads API authentication flow and executes GAQL queries. The Edge Function needs to first exchange the refresh token for a fresh access token by POSTing to https://oauth2.googleapis.com/token with the client credentials and refresh token. This access token is short-lived (1 hour) so the Edge Function should cache it at the module level and refresh when near expiry. Every Google Ads API request needs two headers: Authorization: Bearer {access_token} and developer-token: {developer_token}. For Manager Account setups making calls on behalf of client accounts, also include the login-customer-id header with the MCC customer ID. The Google Ads REST API endpoint for GAQL queries is POST to https://googleads.googleapis.com/v18/customers/{customer_id}/googleAds:search with a JSON body containing { query: 'GAQL query string' }. The response contains a results array where each item has the requested fields nested by resource type.

Lovable Prompt

Create a Supabase Edge Function called google-ads-api that authenticates with Google Ads using OAuth2 refresh token flow. Read all credentials from Deno.env.get(). First fetch a fresh access token from Google OAuth2 endpoint. Then accept a 'query' parameter in the request body and execute it against the Google Ads API search endpoint for the configured customer ID. Include the developer-token header. Return the results array from the Google Ads response.

Paste this in Lovable chat

supabase/functions/google-ads-api/index.ts
1import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
2
3const corsHeaders = {
4 "Access-Control-Allow-Origin": "*",
5 "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
6};
7
8let tokenCache: { token: string; expiry: number } | null = null;
9
10async function getAccessToken(): Promise<string> {
11 if (tokenCache && Date.now() < tokenCache.expiry) return tokenCache.token;
12
13 const response = await fetch("https://oauth2.googleapis.com/token", {
14 method: "POST",
15 headers: { "Content-Type": "application/x-www-form-urlencoded" },
16 body: new URLSearchParams({
17 client_id: Deno.env.get("GOOGLE_ADS_CLIENT_ID")!,
18 client_secret: Deno.env.get("GOOGLE_ADS_CLIENT_SECRET")!,
19 refresh_token: Deno.env.get("GOOGLE_ADS_REFRESH_TOKEN")!,
20 grant_type: "refresh_token",
21 }),
22 });
23
24 const data = await response.json();
25 if (!data.access_token) throw new Error(data.error_description || "OAuth2 token fetch failed");
26
27 tokenCache = { token: data.access_token, expiry: Date.now() + (data.expires_in - 60) * 1000 };
28 return tokenCache.token;
29}
30
31serve(async (req) => {
32 if (req.method === "OPTIONS") {
33 return new Response("ok", { headers: corsHeaders });
34 }
35
36 try {
37 const accessToken = await getAccessToken();
38 const developerToken = Deno.env.get("GOOGLE_ADS_DEVELOPER_TOKEN")!;
39 const customerId = Deno.env.get("GOOGLE_ADS_CUSTOMER_ID")!;
40
41 const { query, loginCustomerId } = await req.json();
42 if (!query) throw new Error("query is required");
43
44 const headers: Record<string, string> = {
45 "Authorization": `Bearer ${accessToken}`,
46 "developer-token": developerToken,
47 "Content-Type": "application/json",
48 };
49
50 if (loginCustomerId) {
51 headers["login-customer-id"] = loginCustomerId;
52 }
53
54 const response = await fetch(
55 `https://googleads.googleapis.com/v18/customers/${customerId}/googleAds:search`,
56 { method: "POST", headers, body: JSON.stringify({ query }) }
57 );
58
59 const data = await response.json();
60 if (!response.ok) throw new Error(JSON.stringify(data.error));
61
62 return new Response(JSON.stringify(data.results || []), {
63 headers: { ...corsHeaders, "Content-Type": "application/json" },
64 });
65 } catch (error) {
66 return new Response(
67 JSON.stringify({ error: error.message }),
68 { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
69 );
70 }
71});

Pro tip: Check the Google Ads API version in the URL (/v18/). The current stable version as of March 2026 may differ — verify at developers.google.com/google-ads/api/docs/release-notes.

Expected result: The google-ads-api Edge Function is deployed and returns campaign data when called with a valid GAQL query.

4

Write GAQL queries and build campaign dashboard

With the Edge Function deployed, ask Lovable to create React components that query Google Ads campaign data using GAQL. GAQL queries follow SQL-like syntax: SELECT {fields} FROM {resource} WHERE {conditions} ORDER BY {field} LIMIT {count}. For campaign performance, the resource is campaign and relevant fields include campaign.id, campaign.name, campaign.status, metrics.impressions, metrics.clicks, metrics.ctr, metrics.average_cpc, metrics.cost_micros, metrics.conversions, and metrics.conversions_value. The WHERE clause uses segments.date_range or DURING for time filtering (e.g., DURING LAST_30_DAYS). Cost in Google Ads API is returned in micros (millionths of the currency unit) — divide by 1,000,000 to get the actual amount. CPC values are also in micros. CTR and conversion rate are returned as decimal values (0.05 = 5%). Build a dashboard with a data table of campaigns, key metric cards showing totals, and a bar chart comparing campaigns by cost or conversions using Recharts which is available in Lovable.

Lovable Prompt

Create a GoogleAdsDashboard React component that calls my google-ads-api Edge Function with a GAQL query to fetch campaign metrics for the last 30 days. The query should select campaign.id, campaign.name, campaign.status, metrics.impressions, metrics.clicks, metrics.ctr, metrics.cost_micros, metrics.conversions from campaign WHERE campaign.status='ENABLED' DURING LAST_30_DAYS. Display a summary row with totals, and a table with each campaign's metrics. Convert cost_micros to dollars by dividing by 1000000.

Paste this in Lovable chat

Pro tip: Google Ads GAQL requires resource fields to include the resource prefix — use campaign.name not just name, and metrics.clicks not just clicks.

Expected result: The dashboard displays live Google Ads campaign data with correct metric values fetched via GAQL.

5

Add keyword performance and budget management views

Extend the dashboard with keyword-level analysis using the keyword_view resource in GAQL. The keyword_view resource allows querying metrics at the individual keyword level, including ad_group_criterion.keyword.text for the keyword, ad_group_criterion.keyword.match_type for match type (BROAD, PHRASE, EXACT), ad_group_criterion.quality_info.quality_score for Quality Score (1-10), and all standard metrics. For budget management, query the campaign_budget resource to show current daily budgets and add a UI for updating them — updating budgets requires a PATCH call to the Google Ads API's MutateCampaignBudgets endpoint, which your Edge Function can proxy by accepting a PUT method with the budget change data. For teams with multiple Ads accounts being managed by an agency using a Manager Account, the login-customer-id header passed to the Edge Function specifies the MCC, while the URL path customer ID specifies which client account to query — this pattern lets one Edge Function serve all client accounts. For complex multi-client reporting setups, RapidDev's team can help architect the data aggregation layer across accounts.

Lovable Prompt

Add a Keywords tab to my Google Ads dashboard that queries the keyword_view resource. Use GAQL to select keyword text, match type, quality score, impressions, clicks, cost_micros, and conversions. Show a table sorted by cost descending. Add a 'Quality Score' color indicator: green for 7-10, yellow for 4-6, red for 1-3.

Paste this in Lovable chat

Pro tip: Keyword quality scores are available in the ad_group_criterion.quality_info.quality_score field, but only for keywords that have received enough impressions to calculate a score — null values should be displayed as 'N/A'.

Expected result: A Keywords tab shows keyword performance with quality score indicators, sortable by cost.

Common use cases

Campaign performance dashboard with key metrics

Display a real-time dashboard showing impressions, clicks, CTR, average CPC, cost, conversions, and ROAS for all active Google Ads campaigns. Filter by date range (last 7 days, last 30 days, custom range) and compare performance across campaigns side by side.

Lovable Prompt

Build a campaign performance dashboard that fetches Google Ads data from an Edge Function using GAQL. Query campaign metrics including impressions, clicks, ctr, average_cpc, cost_micros, and conversions for the last 30 days. Display each campaign as a row in a table with columns for campaign name, status, impressions, clicks, cost (converting from micros), and conversions. Add a date range filter.

Copy this prompt to try it in Lovable

Keyword performance analysis tool

Show which keywords are driving the most conversions and which are wasting budget. Query keyword-level metrics from Google Ads to show cost per conversion, quality score, and impression share for each keyword, helping teams pause underperforming keywords and scale up high-performers.

Lovable Prompt

Create a keyword performance page that queries the keyword_view resource using GAQL via my Google Ads Edge Function. Show keyword text, match type, quality score, impressions, clicks, cost_micros, conversions, and cost_per_conversion. Sort by cost descending. Add a filter to show only keywords with more than 100 impressions in the last 30 days.

Copy this prompt to try it in Lovable

Multi-client MCC reporting for agencies

Agencies managing multiple client Google Ads accounts via a Manager Account (MCC) can build a unified reporting dashboard that shows key metrics across all client accounts in one view, pulling data from multiple customer IDs through the same API credentials.

Lovable Prompt

Build an agency dashboard that lists all client accounts under my Google Ads Manager Account and shows each account's total spend, clicks, and conversions for the current month. Fetch the list of accessible customers from the Google Ads API, then query metrics for each account ID. Display a summary table with sparkline trend charts.

Copy this prompt to try it in Lovable

Troubleshooting

Google Ads API returns 'Developer token is not approved' error

Cause: Your Google Ads developer token is still at 'Test Account' access level and can only make calls to test accounts, not production Google Ads accounts. Or the developer token has not been approved yet.

Solution: Go to Google Ads → Tools & Settings → API Center and check your developer token status. Apply for 'Basic Access' which allows calls to production accounts. This requires agreeing to additional terms and Google's review, which typically takes 1-5 business days. During development, use a test manager account where a test-level token works.

OAuth2 token exchange returns 'invalid_grant' error

Cause: The refresh token has expired or been revoked. Google OAuth2 refresh tokens can be revoked if the user changes their Google password, the application is removed from the Google account, or the token has been unused for 6 months.

Solution: Generate a new refresh token by going through the OAuth consent flow again. Use Google's OAuth Playground at developers.google.com/oauthplayground — select the Google Ads API scope (https://www.googleapis.com/auth/adwords), authorize, then exchange the authorization code for tokens. Copy the new refresh token to GOOGLE_ADS_REFRESH_TOKEN in Cloud Secrets.

GAQL query returns empty results even though campaigns exist

Cause: The GAQL WHERE clause may be filtering out all campaigns. Common issues: filtering by DURING LAST_30_DAYS when there is no data in that range, filtering campaign.status='ENABLED' when campaigns are paused, or the customer ID being queried does not match the account containing the campaigns.

Solution: Start with a minimal GAQL query without WHERE filters to confirm the connection works: SELECT campaign.id, campaign.name FROM campaign. Add filters one at a time to identify which condition is excluding your data. Verify the GOOGLE_ADS_CUSTOMER_ID in Cloud Secrets matches the account with your campaigns (the 10-digit number in the top right of Google Ads).

typescript
1SELECT campaign.id, campaign.name, campaign.status FROM campaign LIMIT 10

Google Ads API returns 403 — 'The caller does not have permission'

Cause: The OAuth2 account used to generate the refresh token does not have access to the Google Ads customer account being queried. Or the account is a Manager Account sub-account that requires the login-customer-id header.

Solution: Verify the Google account that generated the refresh token has access to the target Google Ads customer account. In Google Ads, go to Access & Security to check which users have access. For Manager Account setups, ensure the login-customer-id header is set to the MCC customer ID and the URL path contains the client account's customer ID.

typescript
1headers["login-customer-id"] = mccCustomerId; // MCC account ID

Best practices

  • Cache OAuth2 access tokens at the Edge Function module level for their 1-hour lifetime to avoid unnecessary token refresh calls on every API request
  • Use date range filters in all GAQL queries rather than fetching all-time data — large date ranges on active accounts can return very large datasets that slow your dashboard
  • Store Google Ads report data in Supabase with a timestamp for historical trend analysis — the Google Ads API only returns data for the requested date range, so storing it enables historical comparisons beyond what the API returns in a single query
  • Format cost values carefully — Google Ads API returns all monetary values in micros (millionths). Always divide by 1,000,000 before displaying. Store raw micros values in Supabase for accurate calculations
  • Apply for Basic Access developer token level before going to production — Test Account level tokens cannot access real campaign data
  • Use the login-customer-id header correctly for MCC setups — omitting it when required results in permission errors even with valid credentials
  • Implement GAQL query validation in your Edge Function to reject malformed queries before sending to Google Ads API, preventing unnecessary API calls that count against rate limits

Alternatives

Frequently asked questions

How long does it take to get a Google Ads developer token approved?

Google's review of a developer token application typically takes 1-5 business days. You will receive an email notification when approved or if Google needs more information. During the wait, you can develop and test your integration using a test manager account with a Test Account level token, which allows API access to test accounts without real data.

Can I use a service account instead of OAuth2 with a refresh token for Google Ads API?

Service accounts can be used for Google Ads API but only in very specific configurations — primarily for accessing Manager Account (MCC) data where you have granted the service account access to your Google Ads account. For most individual Google Ads accounts, OAuth2 with a refresh token is the recommended and simpler approach.

What is the Google Ads API rate limit?

The Google Ads API has multiple rate limits: 1,000 operations per API call, 10,000 mutate operations per day (for writing/updating data), and a tokens-per-second rate limit that varies by developer token level. For a reporting dashboard making read-only queries, you are unlikely to hit rate limits. For high-frequency reporting, cache results in Supabase and refresh on a schedule rather than on every page load.

Can I update or create Google Ads campaigns from my Lovable app?

Yes. The Google Ads API supports campaign creation, budget updates, keyword management, and ad group modifications via the Mutate endpoints. These are POST requests to /customers/{customerId}/googleAds:mutate with an operations array. The Edge Function pattern described in this guide works for write operations too — extend the Edge Function to accept mutation operations alongside read queries. Write operations require Basic Access level developer token.

What does GAQL look like and where can I learn it?

GAQL is Google Ads Query Language, which uses SQL-like syntax. A basic query looks like: SELECT campaign.name, metrics.clicks FROM campaign WHERE campaign.status = 'ENABLED' DURING LAST_7_DAYS. Google's documentation at developers.google.com/google-ads/api/fields/v18 provides a complete field reference and query builder tool. The query builder lets you visually select fields and generates the correct GAQL syntax.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.