| name | digital-advertising |
| description | Manage digital advertising campaigns across Meta Ads, Google Ads, LinkedIn Ads, and TikTok Ads using their APIs. Covers campaign creation, budget management, audience targeting, performance analytics, and AI-powered optimization. |
| license | Apache 2.0 |
| tags | ["digital-advertising","meta-ads","google-ads","linkedin-ads","tiktok-ads","ppc","adtech","marketing"] |
| difficulty | intermediate |
| time_to_master | 10-16 weeks |
| version | 1.0.0 |
Digital Advertising Operations
Overview
Digital advertising platforms (Meta, Google, LinkedIn, TikTok) offer APIs that enable programmatic campaign management — creating ads, adjusting budgets, targeting audiences, and analyzing performance. AI agents with access to these APIs can optimize spend, generate ad variants, and provide real-time ROAS insights. This skill covers the major ad platform APIs and automation patterns.
When to Use This Skill
- Building MCP servers for ad campaign management
- Automating cross-platform ad spend optimization
- Creating AI-powered ad copy generation and A/B testing
- Implementing budget pacing and automated bid strategies
- Building unified ad performance dashboards
Core Concepts
Platform API Comparison
| Platform | API | Auth | Spend Share | Best For |
|---|
| Google Ads | REST v16 | OAuth 2.0 | 28% digital | Search, YouTube, Display |
| Meta Ads | Marketing API v19 | System User Token | 22% digital | Social, Instagram, audience targeting |
| LinkedIn Ads | Marketing API | OAuth 2.0 | B2B dominant | B2B targeting by title/company |
| TikTok Ads | Marketing API | Access Token | Fastest growing | Gen Z/Millennial, video |
Campaign Hierarchy
Ad Account
└── Campaign (objective: awareness/traffic/conversions)
└── Ad Set / Ad Group (targeting, budget, schedule)
└── Ad / Creative (copy, image/video, CTA)
Key Metrics
| Metric | Formula | Benchmark |
|---|
| CTR (Click-Through Rate) | Clicks / Impressions | 1-3% (search), 0.5-1.5% (social) |
| CPC (Cost Per Click) | Spend / Clicks | $0.50-$5.00 |
| CPM (Cost Per Mille) | (Spend / Impressions) × 1000 | $5-$30 |
| ROAS (Return on Ad Spend) | Revenue / Ad Spend | 3-5x |
| CPA (Cost Per Acquisition) | Spend / Conversions | Industry-dependent |
| Frequency | Impressions / Reach | < 3 per week |
Implementation Guide
Meta (Facebook/Instagram) Ads API
const campaign = await fetch(
`https://graph.facebook.com/v19.0/act_${adAccountId}/campaigns`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "Q2 Product Launch",
objective: "OUTCOME_SALES",
status: "PAUSED",
special_ad_categories: [],
access_token: META_TOKEN,
}),
}
);
const insights = await fetch(
`https://graph.facebook.com/v19.0/${campaignId}/insights?` +
new URLSearchParams({
fields: "campaign_name,spend,impressions,clicks,ctr,cpc,actions,cost_per_action_type",
date_preset: "last_7d",
access_token: META_TOKEN,
})
);
Google Ads API
from google.ads.googleads.client import GoogleAdsClient
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
ga_service = client.get_service("GoogleAdsService")
query = """
SELECT
campaign.name,
campaign.status,
metrics.impressions,
metrics.clicks,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion
FROM campaign
WHERE segments.date DURING LAST_7_DAYS
AND campaign.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
LIMIT 20
"""
response = ga_service.search(customer_id=CUSTOMER_ID, query=query)
for row in response:
cost = row.metrics.cost_micros / 1_000_000
print(f"{row.campaign.name}: ${cost:.2f} spend, {row.metrics.clicks} clicks, "
f"{row.metrics.conversions:.0f} conversions")
Cross-Platform MCP Server
server.tool(
"get_ad_performance",
"Get ad performance metrics across all platforms for a date range",
{
platform: z.enum(["meta", "google", "linkedin", "tiktok", "all"]),
dateRange: z.enum(["today", "yesterday", "last_7d", "last_30d", "this_month"]),
metric: z.enum(["spend", "impressions", "clicks", "conversions", "roas"]).optional(),
},
async ({ platform, dateRange, metric }) => {
const platforms = platform === "all"
? ["meta", "google", "linkedin", "tiktok"]
: [platform];
const results = await Promise.all(
platforms.map(p => getPerformance(p, dateRange))
);
const combined = results.flat();
const totalSpend = combined.reduce((s, r) => s + r.spend, 0);
const totalRevenue = combined.( s + r., );
{
: [{
: ,
: +
+
+
+
combined.(
+
).(),
}],
};
}
);
server.(
,
,
{
: z.([, , , ]),
: z.(),
: z.().(),
: z.(),
},
({ platform, campaignId, newDailyBudget, reason }) => {
current = (platform, campaignId);
changePercent = ((newDailyBudget - current) / current) * ;
(changePercent > ) {
{
: [{
: ,
: +
,
}],
};
}
(platform, campaignId, newDailyBudget);
{
: [{
: ,
: ,
}],
};
}
);
Budget Pacing Algorithm
def check_budget_pacing(campaign, today):
"""Check if campaign spend is on pace with budget."""
days_in_period = (campaign.end_date - campaign.start_date).days
days_elapsed = (today - campaign.start_date).days
expected_spend_pct = days_elapsed / days_in_period
actual_spend_pct = campaign.spend_to_date / campaign.total_budget
pace = actual_spend_pct / expected_spend_pct if expected_spend_pct > 0 else 0
if pace > 1.15:
return {"status": "overpacing", "action": "reduce_daily_budget", "pace": pace}
elif pace < 0.85:
return {"status": "underpacing", "action": "increase_daily_budget", "pace": pace}
else:
return {"status": "on_pace", "action": "maintain", "pace": pace}
Best Practices
- Start campaigns PAUSED — review before activating to avoid budget waste
- Use conversion APIs alongside pixels — server-side tracking improves attribution
- Set frequency caps — prevent ad fatigue (< 3 impressions/user/week)
- Automate budget pacing — catch overspend/underspend before it impacts results
- A/B test creatives — always run 3-5 ad variants per ad set
- Require approval for budget changes > 20% — protect against runaway spend
Resources
Changelog
| Version | Date | Changes |
|---|
| 1.0.0 | 2026-03-31 | Initial documentation |