Meta Ads

Manage Meta (Facebook) Ads campaigns, ad sets, ads, creatives, and access performance metrics via full read/write API integration.

zachgodsell93

@zachgodsell93

What This Skill Does

Full read/write API integration for managing Meta (Facebook) Ads campaigns, ad sets, ads, and creatives, plus retrieving performance metrics. Requires a Meta access token and ad account ID.

Replaces manual ad management in Meta Ads Manager by enabling programmatic control of campaigns, ad sets, and ads via API.

When to Use It

  • Create and pause Meta ad campaigns programmatically
  • Retrieve performance metrics for campaigns, ad sets, or ads
  • Update targeting, budgets, or optimization goals on existing ad sets
  • Delete underperforming ads or ad sets automatically
  • List all campaigns in an ad account with their status and objectives
  • Generate ad creatives and attach them to ads via API

Install

$ openclaw skills install @zachgodsell93/meta-ads

Meta Ads API

Description

Full read/write integration with Meta (Facebook) Ads API for managing campaigns, ad sets, ads, and accessing performance insights/metrics.

Setup

Environment Variables

  • META_ACCESS_TOKEN - Meta access token (User Access Token or System User Token)
  • META_AD_ACCOUNT_ID - Your ad account ID (numeric, without act_ prefix)

Required Permissions

  • ads_read - Read access to ads data
  • ads_management - Create, edit, and delete ads

Token Types

User Access Token

  • Short-lived: ~2 hours
  • Can be extended to 60-90 days
  • Obtained via OAuth flow or Graph API Explorer

System User Token

  • No expiration
  • Recommended for production/automated access
  • Created in Business Manager

Authentication

All requests require the access token as a query parameter or header:

Authorization: Bearer $META_ACCESS_TOKEN
Content-Type: application/json

Or as query parameter:

?access_token=$META_ACCESS_TOKEN

API Reference

Base URL: https://graph.facebook.com/v25.0/

Important: Ad account IDs must be prefixed with act_ in API calls (e.g., act_123456789).

Ad Account

Get Ad Account Info

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID?fields=name,account_status,currency,timezone_name,amount_spent" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Campaigns

List Campaigns

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/campaigns?fields=id,name,status,objective,daily_budget,lifetime_budget,created_time" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Single Campaign

curl "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}?fields=id,name,status,objective,daily_budget,lifetime_budget,created_time,updated_time" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Create Campaign

curl -X POST "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/campaigns" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Campaign",
    "objective": "OUTCOME_TRAFFIC",
    "status": "PAUSED",
    "special_ad_categories": []
  }'

Update Campaign

curl -X POST "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Campaign Name",
    "status": "ACTIVE"
  }'

Pause Campaign

curl -X POST "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "PAUSED"
  }'

Delete Campaign

curl -X DELETE "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Ad Sets

List Ad Sets

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/adsets?fields=id,name,status,campaign_id,daily_budget,lifetime_budget,targeting,optimization_goal" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Single Ad Set

curl "https://graph.facebook.com/v25.0/{ADSET_ID}?fields=id,name,status,campaign_id,daily_budget,lifetime_budget,targeting,optimization_goal,bid_amount,billing_event" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Create Ad Set

curl -X POST "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/adsets" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Ad Set",
    "campaign_id": "{CAMPAIGN_ID}",
    "daily_budget": 5000,
    "billing_event": "IMPRESSIONS",
    "optimization_goal": "LINK_CLICKS",
    "bid_amount": 200,
    "targeting": {
      "geo_locations": {
        "countries": ["US"]
      },
      "age_min": 18,
      "age_max": 65
    },
    "status": "PAUSED"
  }'

Note: Budget values are in cents (e.g., 5000 = $50.00).

Update Ad Set

curl -X POST "https://graph.facebook.com/v25.0/{ADSET_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Ad Set Name",
    "daily_budget": 10000,
    "status": "ACTIVE"
  }'

Pause Ad Set

curl -X POST "https://graph.facebook.com/v25.0/{ADSET_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "PAUSED"
  }'

Delete Ad Set

curl -X DELETE "https://graph.facebook.com/v25.0/{ADSET_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Ads

List Ads

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/ads?fields=id,name,status,adset_id,campaign_id,creative,created_time" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Single Ad

curl "https://graph.facebook.com/v25.0/{AD_ID}?fields=id,name,status,adset_id,campaign_id,creative,tracking_specs,created_time,updated_time" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Create Ad

curl -X POST "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/ads" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Ad",
    "adset_id": "{ADSET_ID}",
    "creative": {
      "creative_id": "{CREATIVE_ID}"
    },
    "status": "PAUSED"
  }'

Create Ad with Inline Creative

curl -X POST "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/ads" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Ad",
    "adset_id": "{ADSET_ID}",
    "creative": {
      "object_story_spec": {
        "page_id": "{PAGE_ID}",
        "link_data": {
          "link": "https://example.com",
          "message": "Check out our website!",
          "name": "Example Site",
          "call_to_action": {
            "type": "LEARN_MORE"
          }
        }
      }
    },
    "status": "PAUSED"
  }'

Update Ad

curl -X POST "https://graph.facebook.com/v25.0/{AD_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Ad Name",
    "status": "ACTIVE"
  }'

Pause Ad

curl -X POST "https://graph.facebook.com/v25.0/{AD_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "PAUSED"
  }'

Delete Ad

curl -X DELETE "https://graph.facebook.com/v25.0/{AD_ID}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Ad Creatives

List Ad Creatives

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/adcreatives?fields=id,name,object_story_spec,thumbnail_url" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Create Ad Creative

curl -X POST "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/adcreatives" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Creative",
    "object_story_spec": {
      "page_id": "{PAGE_ID}",
      "link_data": {
        "link": "https://example.com",
        "message": "Ad copy text here",
        "name": "Headline",
        "description": "Description text",
        "call_to_action": {
          "type": "SHOP_NOW"
        }
      }
    }
  }'

Insights (Performance Metrics)

Get Account-Level Insights

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/insights?fields=spend,impressions,clicks,reach,cpc,cpm,ctr&date_preset=last_30d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Campaign Insights

curl "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}/insights?fields=spend,impressions,clicks,reach,frequency,cpc,cpm,ctr,actions&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Ad Set Insights

curl "https://graph.facebook.com/v25.0/{ADSET_ID}/insights?fields=spend,impressions,clicks,reach,cpc,cpm,ctr,actions&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Ad Insights

curl "https://graph.facebook.com/v25.0/{AD_ID}/insights?fields=spend,impressions,clicks,reach,cpc,cpm,ctr,actions&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Insights with Custom Date Range

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/insights?fields=spend,impressions,clicks,cpc,cpm,ctr&time_range={\"since\":\"2026-01-01\",\"until\":\"2026-01-31\"}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Insights with Breakdowns

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/insights?fields=spend,impressions,clicks,cpc&breakdowns=age,gender&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Insights by Day

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/insights?fields=spend,impressions,clicks&time_increment=1&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Get Insights with Attribution Window

curl "https://graph.facebook.com/v25.0/{CAMPAIGN_ID}/insights?fields=spend,actions,action_values&action_attribution_windows=[\"7d_click\",\"1d_view\"]&date_preset=last_7d" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Campaign Objectives

ObjectiveDescription
OUTCOME_AWARENESSBrand awareness and reach
OUTCOME_ENGAGEMENTPost engagement, page likes, event responses
OUTCOME_TRAFFICDrive traffic to website or app
OUTCOME_LEADSLead generation
OUTCOME_APP_PROMOTIONApp installs and engagement
OUTCOME_SALESConversions and catalog sales

Legacy objectives (still supported):

  • BRAND_AWARENESS, REACH, LINK_CLICKS, POST_ENGAGEMENT, VIDEO_VIEWS, LEAD_GENERATION, CONVERSIONS, APP_INSTALLS

Targeting Options

Geographic Targeting

{
  "geo_locations": {
    "countries": ["US", "CA"],
    "regions": [{"key": "4081"}],
    "cities": [{"key": "2420379", "radius": 25, "distance_unit": "mile"}],
    "zips": [{"key": "US:90210"}]
  }
}

Demographic Targeting

{
  "age_min": 25,
  "age_max": 54,
  "genders": [1, 2]
}

Gender values: 1 = Male, 2 = Female

Interest Targeting

{
  "flexible_spec": [{
    "interests": [{"id": "6003139266461", "name": "Technology"}]
  }]
}

Budget Types

TypeDescription
daily_budgetMaximum spend per day (in cents)
lifetime_budgetTotal budget for campaign/ad set duration (in cents)

Important: Budget values are in the smallest currency unit (cents for USD). Example: 5000 = $50.00

Status Values

StatusDescription
ACTIVECurrently running
PAUSEDManually paused
DELETEDSoft deleted
ARCHIVEDArchived, not running

Available Metrics

MetricDescription
spendTotal amount spent
impressionsNumber of times ads were shown
clicksNumber of clicks on ads
reachNumber of unique people who saw ads
frequencyAverage number of times each person saw your ad
cpcCost per click
cpmCost per 1,000 impressions
ctrClick-through rate (clicks / impressions)
cppCost per 1,000 people reached
actionsTotal actions (conversions) broken down by type
action_valuesValue of conversions
conversionsNumber of conversions
cost_per_action_typeCost per action by type

Attribution Windows

WindowDescription
1d_click1-day click attribution
7d_click7-day click attribution (default)
28d_click28-day click attribution
1d_view1-day view-through attribution

Note: As of January 2026, 7-day view (7d_view) and 28-day view (28d_view) attribution windows have been removed. Only 1d_view remains for view-through attribution.

Breakdowns

BreakdownDescription
ageAge ranges (18-24, 25-34, etc.)
genderMale, Female, Unknown
placementWhere ad was shown (feed, stories, etc.)
device_platformDevice type (mobile, desktop)
platform_positionPosition within platform
publisher_platformFacebook, Instagram, Audience Network
countryCountry of viewer
regionRegion/state of viewer

Date Presets

PresetDescription
todayToday only
yesterdayYesterday only
this_monthCurrent month
last_monthPrevious month
last_7dLast 7 days
last_14dLast 14 days
last_28dLast 28 days
last_30dLast 30 days
last_90dLast 90 days

Pagination

The API uses cursor-based pagination. Responses include a paging object with cursors.

{
  "data": [...],
  "paging": {
    "cursors": {
      "before": "abc123",
      "after": "xyz789"
    },
    "next": "https://graph.facebook.com/v25.0/..."
  }
}

To get the next page:

curl "https://graph.facebook.com/v25.0/act_$META_AD_ACCOUNT_ID/campaigns?fields=id,name&after={AFTER_CURSOR}" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"

Limits:

  • Default: 25 records per page
  • Maximum: 5000 records per page (use limit parameter)

Rate Limits

Rate limits are calculated per ad account using the formula:

Call Limit = 60 + (400 × Active Ads) - (0.001 × API Errors)
  • Minimum: 60 calls per hour
  • Increases with more active ads
  • Decreases with API errors

Handling Rate Limits:

  • Check X-Business-Use-Case-Usage header for current usage
  • Implement exponential backoff when receiving 429 responses
  • Start with 1 second delay, double on each retry (max 5 retries)

Token Management

Extending User Access Tokens

Short-lived user tokens (~2 hours) can be exchanged for long-lived tokens (60-90 days):

curl "https://graph.facebook.com/v25.0/oauth/access_token?grant_type=fb_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&fb_exchange_token={SHORT_LIVED_TOKEN}"

Response:

{
  "access_token": "long_lived_token_here",
  "token_type": "bearer",
  "expires_in": 5184000
}

Debugging Tokens

Check token validity and permissions:

curl "https://graph.facebook.com/v25.0/debug_token?input_token={TOKEN_TO_CHECK}&access_token={APP_ID}|{APP_SECRET}"

Recommended: System User Tokens

For production use, create a System User in Business Manager:

  1. Go to Business Settings > Users > System Users
  2. Create a new System User with "Admin" role
  3. Assign the ad account to the System User
  4. Generate a token with ads_read and ads_management permissions

System User tokens do not expire.

Changelog

v1.0.0

  • Initial release with full read/write access
  • Ad Account: get info
  • Campaigns: list, get, create, update, pause, delete
  • Ad Sets: list, get, create, update, pause, delete with targeting
  • Ads: list, get, create, update, pause, delete
  • Ad Creatives: list, create
  • Insights: account/campaign/adset/ad level with all metrics
  • Support for breakdowns, date ranges, and attribution windows
  • Campaign objectives and targeting documentation
  • Budget types (daily/lifetime) in cents
  • Pagination documentation
  • Rate limits and token management

Top skills in this category

API Gateway

@byungkyu

Call third-party APIs through the Maton gateway, which injects the credential for an app the user has already connected. Use this skill when the user names a connected app and a concrete action in it - read a mailbox, query a CRM, file an issue, update a spreadsheet, run a query through a connected

39486k

1password

@steipete

Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.

5334k

google-slides

@byungkyu

Google Slides API integration with managed OAuth. Create presentations, add slides, insert content, and manage slide formatting. Use this skill when users want to interact with Google Slides. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Calls run through the `maton` CLI with OAuth login; default to read and list calls, and confirm every write or new connection with the user.

3320k

LinkedIn

@byungkyu

LinkedIn API integration with managed OAuth. Share posts, manage profile, and access LinkedIn features. Use this skill when users want to share content on LinkedIn, get profile/organization information, or interact with LinkedIn's platform. Advertising features (campaigns, ad accounts) require additional OAuth scopes — verify granted scopes before use. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key. Calls run through the `maton` CLI with OAuth login; default to read and list calls, and confirm every write or new connection with the user.

4513k

google-workspace-admin

@byungkyu

Google Workspace Admin SDK integration with managed OAuth. This is a write-capable administrative integration for users, groups, organizational units, roles, and domain settings. Only connect with a least-privileged Google admin account, restrict OAuth scopes to the specific resources needed, and revoke the connection after use. All write operations require explicit user approval showing the exact HTTP method, endpoint path, and target resource identifier before execution. Use this skill only when users need Google Workspace administration. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Calls run through the `maton` CLI with OAuth login; default to read and list calls, and confirm every write or new connection with the user.

2118k