Google Ads API client and MCP server for Cortex ecosystem
npm install @akson/cortex-google-adsTypeScript client for Google Ads API operations, enabling programmatic campaign management, conversion tracking, audience targeting, and performance optimization.
As a PPC Account Manager, I want to retrieve customer account information, so that I can audit account settings and permissions programmatically.
As a Digital Marketing Director, I want to list all accessible customer accounts, so that I can manage multiple client accounts efficiently.
As a Marketing Operations Specialist, I want to validate account access permissions, so that I can ensure API integration has required access levels.
As a Performance Marketing Manager, I want to list all campaigns with their performance metrics, so that I can identify optimization opportunities at scale.
As a SEM Specialist, I want to create new campaigns programmatically, so that I can rapidly deploy campaign structures across multiple accounts.
As a Campaign Manager, I want to update campaign budgets and bidding strategies, so that I can respond to performance changes automatically.
As a Digital Marketing Analyst, I want to pause or activate campaigns based on performance thresholds, so that I can prevent budget waste on underperforming campaigns.
As a Growth Marketing Manager, I want to create conversion actions programmatically, so that I can scale attribution tracking across multiple touchpoints.
As a Marketing Attribution Specialist, I want to list all existing conversion actions, so that I can audit current tracking implementation.
As a Performance Marketing Director, I want to upload offline conversions, so that I can attribute phone calls and in-store purchases to digital campaigns.
As a Ecommerce Marketing Manager, I want to bulk upload conversion data with customer information, so that I can improve audience targeting with first-party data.
As a Customer Acquisition Manager, I want to create customer match audiences, so that I can target similar users for lookalike campaigns.
As a Retention Marketing Specialist, I want to create remarketing audiences based on website behavior, so that I can re-engage users who didn't convert.
As a Data-Driven Marketing Manager, I want to sync CRM data to Google Ads audiences, so that I can create highly targeted campaigns based on customer lifetime value.
As a Marketing Analyst, I want to execute custom GAQL queries, so that I can extract specific performance data for analysis.
As a Performance Marketing Director, I want to generate automated reports on campaign performance, so that I can monitor ROI across all accounts.
As a Digital Marketing Manager, I want to track impression share and competitive metrics, so that I can adjust bidding strategies to maintain market position.
As a Marketing Data Analyst, I want to export detailed conversion path data, so that I can understand multi-touch attribution patterns.
As a SEM Manager, I want to automatically adjust bids based on performance metrics, so that I can maximize ROAS without manual intervention.
As a Performance Marketing Specialist, I want to create and manage responsive search ads at scale, so that I can test ad variations efficiently.
As a Growth Marketing Engineer, I want to integrate Google Ads with marketing automation platforms, so that I can trigger campaign optimizations based on external data.
As a Compliance Manager, I want to audit ad disapprovals and policy violations, so that I can maintain account health across all campaigns.
As a Marketing Operations Manager, I want to validate ad creative compliance before deployment, so that I can prevent policy violations.
As a Brand Marketing Manager, I want to monitor brand safety metrics and negative keywords, so that I can protect brand reputation in search campaigns.
As an Agency Account Director, I want to manage multiple client accounts through a single interface, so that I can scale operations efficiently.
As a Marketing Technology Manager, I want to synchronize campaigns across multiple Google Ads accounts, so that I can maintain consistency for multi-brand companies.
As a Digital Marketing Consultant, I want to benchmark performance across different client accounts, so that I can identify best practices and optimization opportunities.
``bash`
npm install @akson/cortex-google-ads
`typescript
import { GoogleAdsClient } from '@akson/cortex-google-ads';
const client = new GoogleAdsClient({
config: {
customerId: '123-456-7890',
serviceAccount: {
keyFile: 'path/to/service-account.json',
email: 'ads-service@project.iam.gserviceaccount.com'
}
}
});
// Authenticate and get customer info
await client.authenticate();
const customer = await client.getCustomer();
// List campaigns with performance metrics
const campaigns = await client.listCampaigns();
// Create conversion action
await client.createConversionAction({
name: 'Website Purchase',
type: 'WEBPAGE',
category: 'PURCHASE',
value: 100.0,
currency: 'USD'
});
// Upload conversion
await client.uploadConversion({
conversionActionResourceName: 'customers/123456/conversionActions/456789',
gclid: 'gclid_value',
conversionValue: 99.99,
conversionDateTime: new Date().toISOString(),
currencyCode: 'USD'
});
`
`bash`
GOOGLE_ADS_CUSTOMER_ID=123-456-7890
GOOGLE_ADS_DEVELOPER_TOKEN=your-developer-token
GOOGLE_ADS_SERVICE_ACCOUNT_EMAIL=ads-service@project.iam.gserviceaccount.com
GOOGLE_ADS_SERVICE_ACCOUNT_KEY_FILE=path/to/key.json
Create google-ads-config.json:
`json`
{
"customerId": "123-456-7890",
"developerToken": "your-developer-token",
"serviceAccount": {
"email": "ads-service@project.iam.gserviceaccount.com",
"keyFile": "path/to/service-account.json"
}
}
`typescript`
// Authenticate with service account
const authResult = await client.authenticate();
if (!authResult.success) {
throw new Error(authResult.error);
}
`typescript
// Get customer information
const customerResult = await client.getCustomer();
if (customerResult.success) {
console.log('Customer:', customerResult.data);
}
// Get customer with specific ID
const specificCustomer = await client.getCustomer('987-654-3210');
`
`typescriptCampaign: ${campaign.name}, Status: ${campaign.status}
// List all campaigns
const campaignsResult = await client.listCampaigns();
if (campaignsResult.success) {
campaignsResult.data.forEach(campaign => {
console.log();
});
}
// Get campaign performance
const performance = await client.getCampaignPerformance('campaign-id', {
startDate: '2025-01-01',
endDate: '2025-01-31',
metrics: ['clicks', 'impressions', 'conversions', 'cost']
});
`
`typescript
// List conversion actions
const conversionsResult = await client.listConversionActions();
// Create conversion action
const conversionResult = await client.createConversionAction({
name: 'Email Signup',
type: 'WEBPAGE',
category: 'SIGNUP',
value: 10.0,
currency: 'USD',
countingType: 'ONE_PER_CLICK'
});
// Upload single conversion
await client.uploadConversion({
conversionActionResourceName: 'customers/123/conversionActions/456',
gclid: 'Cj0KCQjw...',
conversionValue: 25.99,
conversionDateTime: '2025-01-15T10:30:00+00:00',
currencyCode: 'USD'
});
// Bulk upload conversions
await client.bulkUploadConversions([
{
conversionActionResourceName: 'customers/123/conversionActions/456',
gclid: 'Cj0KCQjw1...',
conversionValue: 99.99,
conversionDateTime: '2025-01-15T14:20:00+00:00',
currencyCode: 'USD'
},
{
conversionActionResourceName: 'customers/123/conversionActions/456',
gclid: 'Cj0KCQjw2...',
conversionValue: 149.99,
conversionDateTime: '2025-01-15T16:45:00+00:00',
currencyCode: 'USD'
}
]);
`
`typescript
// Execute GAQL query
const queryResult = await client.executeQuery({
query:
SELECT
campaign.name,
campaign.status,
metrics.clicks,
metrics.impressions,
metrics.cost_micros
FROM campaign
WHERE campaign.status = 'ENABLED'
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.clicks DESC
LIMIT 10
});
// Query with date range
const dateRangeQuery = await client.executeQuery({
query: 'SELECT campaign.name, metrics.clicks FROM campaign',
customerId: '123-456-7890',
dateRange: {
startDate: '2025-01-01',
endDate: '2025-01-31'
}
});
`
`typescript
// Generate campaign performance report
const report = await client.generateReport({
reportType: 'CAMPAIGN_PERFORMANCE',
dateRange: {
startDate: '2025-01-01',
endDate: '2025-01-31'
},
metrics: ['clicks', 'impressions', 'conversions', 'cost'],
dimensions: ['campaign_name', 'date'],
filters: {
campaignStatus: 'ENABLED'
}
});
// Export report to CSV
await client.exportReportToCSV(report, 'campaign-report.csv');
`
`typescript
// Create customer match audience
const audienceResult = await client.createCustomerMatchAudience({
name: 'VIP Customers',
description: 'High-value repeat customers',
membershipLifespan: 365,
uploadKeyType: 'EMAIL_HASH'
});
// Upload audience members
await client.uploadAudienceMembers(audienceResult.data.resourceName, [
{ hashedEmail: 'hashed_email_1' },
{ hashedEmail: 'hashed_email_2' }
]);
`
All methods return GoogleAdsOperationResult:
`typescript
const result = await client.listCampaigns();
if (result.success) {
console.log('Campaigns:', result.data);
console.log('Total:', result.total);
} else {
console.error('Error:', result.error);
if (result.details) {
console.error('Details:', result.details);
}
}
`
`typescript
class GoogleAdsMonitor {
constructor(private client: GoogleAdsClient) {}
async checkCampaignHealth() {
const campaigns = await this.client.listCampaigns();
if (!campaigns.success) return;
for (const campaign of campaigns.data) {
const performance = await this.client.getCampaignPerformance(campaign.id, {
startDate: '2025-01-01',
endDate: new Date().toISOString().split('T')[0]
});
if (performance.success) {
const ctr = performance.data.clicks / performance.data.impressions;
if (ctr < 0.01) { // CTR below 1%
console.warn(Low CTR alert: ${campaign.name} - ${(ctr * 100).toFixed(2)}%);`
}
}
}
}
}
`typescript
async function optimizeBids() {
const campaigns = await client.listCampaigns();
if (!campaigns.success) return;
for (const campaign of campaigns.data) {
const performance = await client.getCampaignPerformance(campaign.id, {
startDate: new Date(Date.now() - 7 24 60 60 1000).toISOString().split('T')[0],
endDate: new Date().toISOString().split('T')[0]
});
if (performance.success) {
const roas = performance.data.conversionValue / (performance.data.cost / 1000000);
if (roas > 4.0) {
// Increase budget by 10%
await client.updateCampaignBudget(campaign.id, campaign.budget * 1.1);
console.log(Increased budget for high-performing campaign: ${campaign.name});Decreased budget for low-performing campaign: ${campaign.name}
} else if (roas < 2.0) {
// Decrease budget by 10%
await client.updateCampaignBudget(campaign.id, campaign.budget * 0.9);
console.log();`
}
}
}
}
`typescript
class MultiAccountManager {
private clients: Map
addClient(customerId: string, client: GoogleAdsClient) {
this.clients.set(customerId, client);
}
async getCrossAccountPerformance() {
const allPerformance = [];
for (const [customerId, client] of this.clients) {
const campaigns = await client.listCampaigns();
if (campaigns.success) {
allPerformance.push({
customerId,
campaigns: campaigns.data.length,
totalCost: campaigns.data.reduce((sum, c) => sum + (c.cost || 0), 0)
});
}
}
return allPerformance;
}
}
`
`typescript
import express from 'express';
const app = express();
app.post('/optimize-campaigns', async (req, res) => {
const { customerId, threshold } = req.body;
const client = new GoogleAdsClient({
config: { customerId }
});
await client.authenticate();
// Get underperforming campaigns
const campaigns = await client.executeQuery({
query:
SELECT campaign.id, campaign.name, metrics.cost_per_conversion
FROM campaign
WHERE metrics.cost_per_conversion > ${threshold}
AND segments.date DURING LAST_7_DAYS
});
if (campaigns.success) {
for (const campaign of campaigns.data) {
await client.pauseCampaign(campaign.id);
console.log(Paused expensive campaign: ${campaign.name});
}
}
res.json({ success: true, paused: campaigns.data?.length || 0 });
});
`
`typescript
async function syncCRMConversions() {
// Fetch conversions from CRM
const crmConversions = await fetchFromCRM();
const conversions = crmConversions.map(crm => ({
conversionActionResourceName: 'customers/123/conversionActions/456',
gclid: crm.gclid,
conversionValue: crm.orderValue,
conversionDateTime: crm.purchaseDate,
currencyCode: 'USD',
orderId: crm.orderId
}));
await client.bulkUploadConversions(conversions);
console.log(Uploaded ${conversions.length} CRM conversions);`
}
This section consolidates the function-level documentation that previously lived in FUNCTIONS.md.
#### getConversionMetrics
Get detailed conversion metrics with attribution analysis.
`typescript
const metrics = await getConversionMetrics(client, {
startDate: '2024-01-01',
endDate: '2024-01-31',
conversionActionId: '123456' // optional
});
// Returns: ConversionMetrics[]
// - totalConversions, totalValue, averageValue
// - Device breakdown, top keywords/campaigns
// - Conversion paths and attribution data
`
#### getConversionActions
List conversion actions with configuration details.
`typescript
const actions = await getConversionActions(client, {
includeHidden: false
});
// Returns conversion action configurations including:
// - Value settings, counting type, attribution model
// - Lookback windows and tag snippets
`
#### getAttributionModels
Compare attribution models for conversions.
`typescript
const models = await getAttributionModels(client, {
startDate: '2024-01-01',
endDate: '2024-01-31',
conversionActionId: '123456'
});
// Returns AttributionModel comparisons with:
// - Current model performance
// - Alternative simulations
// - Impact on conversion credit distribution
`
#### getConversionPaths
Analyze multi-touch conversion paths.
`typescript
const paths = await getConversionPaths(client, {
startDate: '2024-01-01',
endDate: '2024-01-31',
minPathLength: 2
});
// Returns ConversionPathAnalysis including:
// - Average path length and time to conversion
// - Top conversion paths
// - Channel assists and interactions
`
#### getCampaignPerformance
Comprehensive campaign performance with trends.
`typescript
const campaigns = await getCampaignPerformance(client, {
startDate: '2024-01-01',
endDate: '2024-01-31',
campaignIds: ['123', '456'], // optional
includeRemoved: false
});
// Returns CampaignPerformance[] with:
// - Metrics: impressions, clicks, CTR, conversions, ROAS
// - Trends: period-over-period changes
// - Optimization score and recommendations
// - Impression share metrics
`
#### getAuctionInsights
Deep-dive competitor metrics for campaigns.
`typescript
const insights = await getAuctionInsights(client, {
customerId: '123-456-7890',
campaignIds: ['123'],
dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' }
});
// Returns competitor impression share, overlap rate, and outranking share.
`
#### getCampaignRecommendations
Retrieve Google Ads optimization recommendations.
`typescript`
const recommendations = await getCampaignRecommendations(client, {
customerId: '123-456-7890',
filters: ['KEYWORD'],
});
#### getKeywordPerformance
Detailed keyword metrics with quality scores.
`typescript`
const keywords = await getKeywordPerformance(client, {
customerId: '123-456-7890',
dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' },
metrics: {
includeQualityScore: true,
includeSearchImpressionShare: true,
},
});
#### getNegativeKeywords
Retrieve negative keyword lists per campaign.
`typescript`
const negatives = await getNegativeKeywords(client, {
customerId: '123-456-7890',
campaignId: '9876543210'
});
#### getAudiencePerformance
Audience performance with segmentation.
`typescript`
const audiences = await getAudiencePerformance(client, {
customerId: '123-456-7890',
segments: ['DEVICE', 'LOCATION']
});
#### getCustomerMatchLists
Customer match audience metadata and size estimates.
`typescript`
const lists = await getCustomerMatchLists(client, {
customerId: '123-456-7890'
});
#### getAuctionInsights
Retrieve auction insights for account- or campaign-level analysis (see example above).
#### getSearchImpressionShare
`typescript`
const impressionShare = await getSearchImpressionShare(client, {
customerId: '123-456-7890',
campaignId: '123',
dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' }
});
#### getSegmentPerformance
`typescript`
const segments = await getSegmentPerformance(client, {
customerId: '123-456-7890',
dimensions: ['DEVICE', 'DAY_OF_WEEK'],
metrics: ['impressions', 'clicks', 'conversions']
});
#### runAdvancedQuery
Execute custom GAQL queries with typed responses.
`typescript
const report = await runAdvancedQuery(client, {
customerId: '123-456-7890',
query:
SELECT
campaign.id,
campaign.name,
metrics.conversions,
metrics.conversion_value
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
,`
});
Full TypeScript definitions included:
`typescript``
import type {
GoogleAdsCustomer,
GoogleAdsCampaign,
GoogleAdsConversionAction,
ConversionUpload,
GoogleAdsQuery,
GoogleAdsReport,
ReportOptions,
GoogleAdsOperationResult,
GoogleAdsListResult
} from '@akson/cortex-google-ads';
- Node.js ≥18.0.0
- Google Ads API access and developer token
- Service account with Google Ads API permissions
- Valid Google Ads customer account
MIT