Meta Ads

Live

OAUTH 2.0

AD CAMPAIGNS

Marketing

Meta Ads gives your agent ad campaign control: build campaigns, ad sets, and ads, pull performance insights, manage custom audiences, and run product catalogs.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Meta Ads
agent · Acme Q3
Run
Which ad sets in the Spring Sale campaign spent the most last week, and at what CPC?
S
metaads_account_insights_get
138ms
Ads agent
Retargeting US spent $4,210 at a $0.82 CPC, ahead of Lookalike 1% at $3,180 and a $1.14 CPC. The other 4 ad sets spent under $900 each.
Sources: Spring Sale campaign, 6 ad sets, last 7 days
metaads
6 ad sets
18:29
Message Claude...

Tools your ads agent reaches for on Meta Ads, scoped per user.

CALL ANY TOOL
148 tools for Meta ad campaigns: campaigns, ad sets, ads, creatives, insights reports, custom audiences, pixels, product catalogs, and Commerce orders.
metaads_account_insights_create_report_run
Run account insights create report
Start an asynchronous Ads Insights report job for an ad account, using the same field/level/breakdown/date parameters as a synchronous insights request. Returns {report_run_id: "<id>"} immediately; the job continues running server-side after this call returns. Use this instead of metaads_account_insights_get for large or high-cardinality pulls (many breakdowns, long date ranges, reach breakdowns on data older than 13 months) that risk timing out or being truncated synchronously; poll metaads_report_run_get_status with the returned report_run_id, then fetch rows with metaads_report_run_get_insights once it reports Job Completed. report_run_id expires 30 days after creation -- do not store it for long-term use; reach-breakdown async requests on data older than 13 months are capped at 10 per ad account per day.
Parameters
Name
Type
Required
Description
ad_account_id
string
Required
Meta Ads ad account ID to run the insights report against, without the leading 'act_' prefix (the tool adds it automatically). Example: 123456789012345.
action_attribution_windows
string
Optional
Comma-separated attribution windows to apply to action-based metrics, e.g. "1d_view,7d_click". If omitted, Meta uses the ad account's default attribution setting.
action_breakdowns
string
Optional
Comma-separated dimensions used to segment the 'actions' and other action-based metrics, e.g. "action_type" or "action_type,action_device". Defaults to action_type if omitted. Default: `action_type`.
breakdowns
string
Optional
Comma-separated dimensions to segment results by, e.g. "age,gender" or a reach-related breakdown for historical data. Required (via the async path) for reach breakdowns on data older than 13 months, which are capped at 10 requests per ad account per day.
date_preset
string
Optional
Predefined date range for the metrics window, e.g. last_30d or maximum (Meta's cap of 37 months back). Mutually exclusive with time_range and time_ranges -- provide only one of the three. One of: `today`, `yesterday`, `this_month`, `last_month`, `this_quarter`, `maximum`, `data_maximum`, `last_3d`, `last_7d`, `last_14d`, `last_28d`, `last_30d`, `last_90d`, `last_week_mon_sun`, `last_week_sun_sat`, `last_quarter`, `last_year`, `this_week_mon_today`, `this_week_sun_today`, `this_year`.
export_format
string
Optional
Request a downloadable export of the report instead of (or in addition to) JSON results. 'csv' produces a comma-separated file, 'xls' produces an Excel file. Leave blank for a plain JSON result set. One of: `csv`, `xls`.
export_name
string
Optional
Display name for the exported report file, used only when export_format is set.
fields
string
Optional
Comma-separated list of insight metrics to return, e.g. "impressions,clicks,spend,ctr,actions,reach". If omitted, Meta returns a small default metric set (impressions and spend).
filtering
string
Optional
JSON array, as a string, of filter objects in {field, operator, value} form to restrict which insight rows are returned, e.g. [{"field":"campaign.name","operator":"CONTAIN","value":"Sale"}].
level
string
Optional
Aggregation grain for the returned rows: 'account' rolls everything into one row per account, 'campaign'/'adset'/'ad' return one row per entity at that level. One of: `account`, `campaign`, `adset`, `ad`. Default: `account`.
time_increment
string
Optional
Splits the requested time range into smaller windows. Use a number of days (as a string, e.g. "1" for daily rows), "all_days" for one row per day across the whole range, or "monthly" for one row per month. If omitted, Meta returns one aggregated row for the whole range.
time_range
object
Optional
Custom single date range {since, until} (each formatted "YYYY-MM-DD") for the metrics window. Example: {"since": "2026-08-01", "until": "2026-08-31"}. Cannot start more than 37 months in the past. Mutually exclusive with date_preset and time_ranges.
time_ranges
array
Optional
Array of custom {since, until} date ranges (each formatted "YYYY-MM-DD") to compare in a single call, e.g. [{"since": "2026-07-01", "until": "2026-07-31"}, {"since": "2026-08-01", "until": "2026-08-31"}]. Overrides time_range and date_preset when provided.
use_account_attribution_setting
boolean
Optional
When true, ignore action_attribution_windows and use the ad account's own configured attribution setting instead. Defaults to false. Default: `false`.
metaads_account_insights_get
Get account insights
metaads_ad_copy
Copy ad
metaads_ad_delete
Delete ad
metaads_ad_list
List ad
metaads_ad_update
Update ad
metaads_adaccount_get_delivery_estimate
Adaccount get delivery estimate
metaads_adaccount_remove_user
Adaccount remove user
metaads_adimage_create
Create adimage
metaads_adrule_list_history
Adrule list history
metaads_adset_delete
Delete adset
metaads_adset_get_delivery_estimate
Adset get delivery estimate
metaads_adset_update
Update adset
metaads_adspixel_send_events
Adspixel send events
metaads_business_create_system_user
Business create system user
metaads_business_get
Get business
metaads_business_list_owned_ad_accounts
Business list owned ad accounts
metaads_customaudience_add_users
Customaudience add users
metaads_customaudience_delete
Delete customaudience
metaads_customaudience_unshare
Customaudience unshare
metaads_customaudience_update
Update customaudience
metaads_lead_get
Get lead
metaads_leadgen_form_list_leads
Leadgen form list leads
metaads_offline_event_set_upload_events
Offline event set upload events
metaads_order_cancel
Cancel order
metaads_order_shipment_create
Create order shipment
metaads_product_feed_list
List product feed
metaads_product_feed_upload_get
Get product feed upload
metaads_productitem_batch_upsert
Upsert productitem batch
metaads_targeting_search
Search targeting

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Meta Ads tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["metaads"], toolNames: [
    "metaads_campaign_list",
    "metaads_account_insights_get",
    "metaads_adset_update"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Show spend and CPC by ad set for the Spring Sale campaign last week" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["metaads"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Show spend and CPC by ad set for the Spring Sale campaign last week" }],
  tools,
});

// Execute the tool call with the user's vaulted Meta Ads token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["metaads"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Show spend and CPC by ad set for the Spring Sale campaign last week" }],
  tools,
});

// Tool call runs with the user's vaulted Meta Ads token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["metaads"] }, pageSize: 100,
});

const agent = new Agent({
  name: "ads_agent",
  model: "gemini-2.5-pro",
  instruction: "Meta Ads tools scoped to this user",
  tools,
});

await agent.run("Show spend and CPC by ad set for the Spring Sale campaign last week");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Meta Ads tool. Click to copy, paste into your agent, done.
Campaigns and ads
Copy the prompt
Copied
List active campaigns in our ad account with their objectives.
Copy the prompt
Copied
Pause the ad sets in the Spring Sale campaign with a CPC above $2.
Copy the prompt
Copied
Duplicate the Retargeting US ad set into the Summer campaign.
Insights and reports
Copy the prompt
Copied
Show spend, clicks, and CPC by campaign for the last 7 days.
Copy the prompt
Copied
Start an insights report for Q3 broken down by age and gender.
Copy the prompt
Copied
Get impressions and conversions for this ad yesterday.
Audiences and catalogs
Copy the prompt
Copied
Create a 1% lookalike audience from our Purchasers custom audience.
Copy the prompt
Copied
List product items in the Main catalog with data-quality errors.
Copy the prompt
Copied
Show firing stats for our Meta Pixel over the last 24 hours.
SEE HOW AUTH WORKS
Each user signs in to Meta Ads once; Scalekit stores and refreshes their tokens. Every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Meta Ads
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Meta Ads
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Meta Ads
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Meta Ads
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other marketing and ads connectors.
GTM and RevOps Teams
Revenue forecast commentary
Pulls open pipeline from Salesforce and HubSpot, calculates coverage against quota, flags at-risk stages, posts commentary to Slack, and logs every snapshot to Google Sheets.
GTM and RevOps Teams
Competitive intelligence briefing agent
Scans Gong calls for competitor mentions, matches each one to its Notion battlecard, and DMs every affected rep a single Slack digest per cycle. Every call runs as the PMM who owns the briefing, never a shared bot.
GTM and RevOps Teams
CRM AI agent
Reads the Granola transcript after every call, extracts next steps and updates the HubSpot record, drafts the follow-up in Gmail, and confirms in Slack, all on the rep's own delegated OAuth.
GTM and RevOps Teams
Outbound prospecting agent
Searches Apollo for prospects matching your ICP, scores and ranks them, drafts personalized outreach in Gmail, and logs every send to Google Sheets. Mail goes out as the rep, not from a shared inbox.
Test other agents
See the same per-user auth pattern across other marketing and ads connectors.
GTM
Revenue forecast agent
Score pipeline coverage against quota across Salesforce and HubSpot, post forecast commentary to Slack, log snapshots to Sheets.
GTM
Competitive intelligence briefing agent
Scan Gong calls for competitor mentions, match each one to its Notion battlecard, and DM every affected rep a single Slack digest.
GTM
CRM AI agent
Turn each Granola call transcript into a HubSpot record update, a drafted Gmail follow-up, and a Slack recap.
SALES
Outbound prospecting agent
Search Apollo for ICP matches, rank them, draft personalised Gmail outreach, and log every send to Google Sheets.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Meta Ads token looks fine in a demo. In production every budget change looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Meta Ads today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Meta Ads as the user or through a shared key?
As the user. Each user signs in to Meta Ads once, and Scalekit stores and refreshes their tokens. Audit logs attribute every campaign change to that user, not a shared service account.
Where is the Meta Ads OAuth token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Meta Ads?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example the insights and list tools for a reporting agent. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Meta Ads access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Can the agent delete campaigns or audiences?
Only if you expose those tools. metaads_ad_delete is a soft delete that sets the ad to DELETED, while metaads_customaudience_delete and metaads_productcatalog_delete are permanent. Leave the 20 destructive tools out of listScopedTools for agents that should only report and optimize.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""metaads"": {
""url"": ""https://mcp.scalekit.com/metaads"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.metaads]
url = ""https://mcp.scalekit.com/metaads""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""metaads"": {
""url"": ""https://mcp.scalekit.com/metaads"",
""type"": ""http""
}
}
}