CredentialWhere to GetUsed ForOAuth ScopeMETA_ACCESS_TOKENMeta Developer Console → Graph API Explorer → Generate TokenAll Meta Marketing API callsads_management (read+write)META_AD_ACCOUNT_IDAds Manager URL: adsmanager.facebook.com/act_XXXXXXXXXAll campaign operations—
META_APP_ID and META_APP_SECRET are not needed — the access token alone is sufficient for all API operations.
Use exec + curl with your META_ACCESS_TOKEN. All requests go to https://graph.facebook.com/v21.0/.
Example structure:
bash
curl -X POST "https://graph.facebook.com/v21.0/act_{AD_ACCOUNT_ID}/campaigns" \
-d "access_token={META_ACCESS_TOKEN}" \
-d "name=My Campaign" \
-d "objective=LEADS" \
-d "status=PAUSED"
When user wants to launch a new campaign, make changes to an existing one, or do any campaign management task. Requires META_ACCESS_TOKEN and META_AD_ACCOUNT_ID.
Required credentials:
If credentials are not yet configured: Guide the user to get them:
Store credentials securely. Never paste tokens into open conversation unless absolutely necessary.
POST to /act_{AD_ACCOUNT_ID}/campaigns
POST to /act_{AD_ACCOUNT_ID}/adsets
Upload image first: POST /act_{AD_ACCOUNT_ID}/adimages Then reference image_hash in creative.
POST to /act_{AD_ACCOUNT_ID}/ads
Before setting status to ACTIVE, verify all of the following:
PATCH /act_{AD_ACCOUNT_ID}/adsets?ids=[ADSET_ID] Set status to PAUSED or ACTIVE.
PATCH /act_{AD_ACCOUNT_ID}/adsets?ids=[ADSET_ID] Set new daily_budget or lifetime_budget. Rule: Change by max 20% per adjustment to avoid disrupting learning.
GET /act_{AD_ACCOUNT_ID}/campaigns?fields=id,name,status,objective,daily_budget
GET /act_{AD_ACCOUNT_ID}/insights?fields=spend,impressions,clicks,results,cpc,cpm,ctr&level=[campaign|adset|ad]&time_range={'since':'YYYY-MM-DD','until':'YYYY-MM-DD'}
When you have a winner campaign and want to replicate it to a new audience, geo, or offer, follow these 6 steps:
Step 1: Get source campaign structure
text
GET https://graph.facebook.com/v21.0/[CAMPAIGN_ID]?fields=id,name,status,objective,daily_budget&access_token=[TOKEN]
Step 2: Get source adsets
text
GET https://graph.facebook.com/v21.0/[ADSET_ID]?fields=id,name,status,optimization_goal,targeting,daily_budget,bid_amount&access_token=[TOKEN]
Step 3: Get source ads
text
GET https://graph.facebook.com/v21.0/[AD_ID]?fields=id,name,status,creative&access_token=[TOKEN]
Step 4: Create new campaign (PAUSED)
text
POST https://graph.facebook.com/v21.0/act_[AD_ACCOUNT_ID]/campaigns
access_token=[TOKEN]
name=[NEW_NAME — e.g. "Didoo AI — US — Interest — 2026-04-14"]
objective=[SAME AS SOURCE]
status=PAUSED
budget_type=DAILY
Step 5: Create new adset(s) with modified targeting/budget
text
POST https://graph.facebook.com/v21.0/act_[AD_ACCOUNT_ID]/adsets
access_token=[TOKEN]
campaign_id=[NEW CAMPAIGN ID]
name=[NEW ADSET NAME]
optimization_goal=[SAME AS SOURCE — e.g. LEAD_GENERATION]
targeting=[MODIFIED — change geo, age, interests, etc.]
daily_budget=[NEW BUDGET — integer in cents, e.g. 5000 = $50/day]
status=PAUSED
Step 6: Create new ad(s)
text
POST https://graph.facebook.com/v21.0/act_[AD_ACCOUNT_ID]/ads
access_token=[TOKEN]
adset_id=[NEW ADSET ID]
name=[NEW AD NAME]
creative={'creative_id': '[NEW_CREATIVE_ID]'}
status=PAUSED
Review BEFORE activating:
IssueCheckCampaign not deliveringIs status ACTIVE? Is budget more than $5/day? Is targeting too narrow?Ads in Learning LimitedNeed ~50 results/week to exit; increase budget or consolidate adsetsHigh frequencyExpand audience or rotate new creativeLow CTRTest new creative; check if audience matches the hookCost per result too highCheck if budget is realistic; test narrower targeting