Create and manage Meta (Facebook/Instagram) ad campaigns from your terminal.
Built by Attainment Labs
Meta Ads Manager is slow. Clicking through 15 screens to launch a campaign is a waste of time when you already know what you want to run.
This tool lets you define a campaign in a YAML file and deploy it with one command.
meta-ads create --config campaign.yaml
One campaign. One ad set. Multiple ads. All created in seconds.
pip install meta-ads-cliOr install from source:
git clone https://github.com/attainmentlabs/meta-ads-cli.git
cd meta-ads-cli
pip install -e .1. Set up your credentials
cp .env.example .env
# Edit .env with your Meta access token, ad account ID, and page ID2. Create your campaign config
cp campaign.example.yaml campaign.yaml
# Edit campaign.yaml with your ad copy, images, targeting, and budget3. Validate your config
meta-ads validate --config campaign.yaml4. Preview with dry run
meta-ads create --config campaign.yaml --dry-run5. Deploy
meta-ads create --config campaign.yamlYour campaign is created as PAUSED by default. Review it in Ads Manager, then activate it when ready.
Create a .env file in your project root (or export these in your shell):
| Variable | Required | Description |
|---|---|---|
META_ACCESS_TOKEN |
Yes | Your Meta API access token |
META_AD_ACCOUNT_ID |
Yes | Your ad account ID (numbers only, no act_ prefix) |
META_PAGE_ID |
Yes | Your Facebook Page ID |
META_API_VERSION |
No | API version (default: v21.0) |
Your campaign is defined in a single YAML file. Here is the full schema:
campaign:
name: "My Campaign"
objective: OUTCOME_TRAFFIC # See objectives below
status: PAUSED # PAUSED or ACTIVE
special_ad_categories: [] # Leave empty unless required
ad_set:
name: "My Ad Set"
daily_budget: 1000 # In cents. 1000 = $10/day
optimization_goal: LINK_CLICKS # See optimization goals below
targeting:
age_min: 18
age_max: 65
genders: [0] # 0 = all, 1 = male, 2 = female
countries: ["US"]
interests: # Optional
- id: "6003139266461"
name: "Fitness and wellness"
platforms: ["facebook", "instagram"]
facebook_positions: ["feed"]
instagram_positions: ["stream", "story", "reels"]
ads:
- name: "My Ad"
image: ./images/ad.png # Path relative to YAML file
primary_text: "Your ad copy."
headline: "Your Headline"
description: "Short description"
cta: LEARN_MORE # See CTAs below
link: "https://example.com"Campaign Objectives: OUTCOME_TRAFFIC, OUTCOME_AWARENESS, OUTCOME_ENGAGEMENT, OUTCOME_LEADS, OUTCOME_SALES, OUTCOME_APP_PROMOTION
Optimization Goals: LINK_CLICKS, IMPRESSIONS, REACH, LANDING_PAGE_VIEWS, APP_INSTALLS, OFFSITE_CONVERSIONS, LEAD_GENERATION
CTA Options: LEARN_MORE, SIGN_UP, DOWNLOAD, SHOP_NOW, BOOK_NOW, GET_OFFER, SUBSCRIBE, CONTACT_US, APPLY_NOW, WATCH_MORE
Create a full campaign from your YAML config.
# Preview first
meta-ads create --dry-run
# Deploy (will ask for confirmation)
meta-ads create
# Deploy without confirmation
meta-ads create --yes
# Use a custom config file
meta-ads create --config path/to/campaign.yamlCheck the status of a campaign and all its ads.
meta-ads status 120243616427570285Pause a running campaign.
meta-ads pause 120243616427570285Activate a paused campaign. This starts spending your budget.
meta-ads activate 120243616427570285Permanently delete a campaign.
meta-ads delete 120243616427570285Validate your YAML config without making any API calls.
meta-ads validate --config campaign.yamlThis is the part most people get stuck on. Here is the short version:
- Go to Meta for Developers and create an app (type: Business)
- Open the Graph API Explorer
- Select your app, then request these permissions:
ads_management,pages_read_engagement,pages_show_list - Click "Generate Access Token" and authorize
- Copy the token to your
.envfile
Important: Graph API Explorer tokens expire after about 2 hours. For production use, exchange it for a long-lived token:
curl "https://graph.facebook.com/v21.0/oauth/access_token?\
grant_type=fb_exchange_token&\
client_id=YOUR_APP_ID&\
client_secret=YOUR_APP_SECRET&\
fb_exchange_token=YOUR_SHORT_LIVED_TOKEN"Long-lived tokens last about 60 days.
Interest targeting requires Meta's internal IDs. Search for them using the API:
curl "https://graph.facebook.com/v21.0/search?\
type=adinterest&\
q=fitness&\
access_token=YOUR_TOKEN"This returns interest names and IDs you can use in your campaign YAML.
See the examples/ directory for ready-to-customize campaign configs:
- ecommerce.yaml: Product launch targeting skincare enthusiasts
- app-install.yaml: Mobile app install campaign for fitness users
This tool wraps the Meta Marketing API with requests. No heavy SDKs. The full chain:
- Uploads your ad images to your ad account
- Creates a campaign with your objective
- Creates an ad set with your budget and targeting
- Creates ad creatives linking your images and copy
- Creates ads linking creatives to the ad set
Everything is created as PAUSED by default so you can review before spending.
We wrote a free guide covering Meta Ads automation end to end: OAuth setup walkthrough, audience segmentation strategy, budget allocation frameworks, creative testing, scaling rules, and common API errors with fixes.
Get the Guide: The Engineer's Playbook for Meta Ads
PRs welcome. Keep it simple. This tool is intentionally lightweight.
git clone https://github.com/attainmentlabs/meta-ads-cli.git
cd meta-ads-cli
pip install -e .
meta-ads --helpMIT. See LICENSE.