Meta requires an access token. Store it once in your OS credential store:
Primary command
Authenticate
bash
agent-adsmetaauthset
For CI, headless Linux, or one-off overrides, you can still set a shell variable for the current process:
bash
exportMETA_ADS_ACCESS_TOKEN=EAABs...
Required permission:ads_read — read access to campaigns, insights, creatives, and pixels.
Optional permission:business_management — discover businesses and ad accounts (businesses list, ad-accounts list). Without it, you can still query any account directly if you know its ID.
Both permissions are read-only. The CLI never creates, modifies, or deletes anything.
Generate a token at the Graph API Explorer — select your app, add the permissions above, and click "Generate Access Token".
On Linux, persistent secure storage requires a running Secret Service provider such as GNOME Keyring or KWallet. If secure storage is unavailable, use META_ADS_ACCESS_TOKEN in the shell for that session.
02
Step 02
Verify your setup
Add --api to also ping the Meta API and confirm your token works.
Primary command
Verify your setup
bash
agent-adsmetadoctor
json
{"ok":true,"checks":[{"name":"credential_store","ok":true,"detail":"stored Meta token found in OS credential store"},{"name":"config_file","ok":true,"detail":"using /work/agent-ads.config.json"},{"name":"access_token","ok":true,"detail":"using stored Meta token from the OS credential store"}]}
Add --api to also ping the Meta API and confirm your token works.
03
Step 03
Discover your accounts
Primary command
Discover your accounts
bash
# List businesses you have access toagent-adsmetabusinesseslist# List ad accounts under a businessagent-adsmetaad-accountslist--business-id1234567890
json
[{"id":"act_1234567890","name":"My Ad Account","account_status":1,"currency":"USD"}]
7 guides — exact flags, auth details, and workflow notes.
Guide
Meta Guide
This is the routing guide for the Meta provider. Read this first when the user wants to work with Meta (Facebook/Instagram) ads. Then load only the specific reference file linked below.
Load only the reference file you need. Do not preload all of them.
Common Mistakes
Forgetting META_ADS_ACCESS_TOKEN before running API commands
Passing both --account and --object to insights commands (they are mutually exclusive)
Using --action-breakdowns without actions in --fields
Treating default JSON output as if it includes meta, paging, or warnings (it doesn't — use --envelope)
Assuming pixel-health is a raw EMQ passthrough (it's a combined diagnostic view)
Forgetting --all or --max-items when paginating (you only get one page by default)
Guide
Meta Auth And Output
Use this file for local setup, authentication, config resolution, and output behavior.
First command
Meta Auth And Output
bash
agent-adsmetaauthset
Authentication
Two environment variables control Meta API access:
Variable
Required
Purpose
META_ADS_ACCESS_TOKEN
Yes
Bearer token for all Meta API calls
Required permissions
Permission
Needed for
ads_read
All --account commands: campaigns, insights, creatives, pixels
business_management
businesses list and ad-accounts list (discovery)
Both are read-only — no write access is granted. Generate a token at the Graph API Explorer with the permissions above.
Secrets are never read from CLI flags or config files. Persistent secrets live in the OS credential store, and shell env remains available for overrides or CI.
Setting up auth
Option 1 — store the token in the OS credential store:
bash
agent-adsmetaauthset
Option 2 — shell environment override:
bash
exportMETA_ADS_ACCESS_TOKEN=EAABs...
On Linux, persistent secure storage requires a running Secret Service provider such as GNOME Keyring or KWallet. In headless environments, use the shell variable for that process.
Verifying auth
bash
# Check config and env without hitting the APIagent-adsmetadoctor# Also ping the API to confirm the token worksagent-adsmetadoctor--api
Example doctor output:
json
{"ok":true,"checks":[{"name":"credential_store","ok":true,"detail":"stored Meta token found in OS credential store"},{"name":"config_file","ok":true,"detail":"using /work/agent-ads.config.json"},{"name":"access_token","ok":true,"detail":"using stored Meta token from the OS credential store"},{"name":"api_ping","ok":true,"detail":"token accepted by Meta API; sampled 1 business record(s)"}]}
Config Resolution
Precedence (highest to lowest):
Shell META_ADS_ACCESS_TOKEN
OS credential store for the token
For non-secret config:
CLI flags (--api-version v24.0)
Shell environment variables
agent-ads.config.json file values
Config file
Default path: agent-ads.config.json in the current directory. Override with --config <path>.
Supported keys under providers.meta:
Key
Default
Description
api_base_url
https://graph.facebook.com
Meta Graph API base URL
api_version
v25.0
API version
timeout_seconds
60
HTTP request timeout
default_business_id
none
Fallback for --business-id
default_account_id
none
Fallback for --account
output_format
json
Default output format
Inspecting config
bash
# Show the resolved config file pathagent-adsmetaconfigpath# Show the full resolved configuration (all sources merged)agent-adsmetaconfigshow# Validate the config file parses correctlyagent-adsmetaconfigvalidate
Output
Formats
Flag
Behavior
Best for
--format json (default)
JSON array or object
Automation, piping to jq
--format jsonl
One JSON object per line
Streaming, line-by-line processing
--format csv
CSV with header row
Spreadsheets, data import
Default output (data-only)
By default, stdout contains only the data — no metadata wrapper:
json
[{"id":"act_123","name":"Agency Account"}]
Envelope mode
Add --envelope to wrap data with response metadata, paging cursors, and warnings:
Ad account ID (omit if default_account_id is set in config)
--fields <list>
Comma-separated field names
--fields-file <path>
Read field names from a file (comma or newline separated, - for stdin)
--page-size <n>
Items per API request
--cursor <token>
Resume from a cursor
--all
Auto-paginate through all results
--max-items <n>
Stop after collecting N items
Account ID Normalization
Account IDs accept either raw numeric (1234567890) or prefixed (act_1234567890) format. The CLI always normalizes to act_<id> before making API calls. Output also uses the act_ prefix.
Guide
Meta Reports
Use this file for insights query (synchronous), insights export (high-level async), and report-runs (explicit async lifecycle).
JSON file containing a filter array (use - for stdin)
--sort <list>
Comma-separated: spend_descending, impressions_ascending, etc.
Fields
Flag
Description
--fields <list>
Comma-separated field names
--fields-file <path>
Read fields from file (comma or newline separated, - for stdin)
If no fields are specified, defaults to: account_id, account_name, campaign_id, campaign_name, impressions, clicks, spend.
Pagination
Flag
Description
--page-size <n>
Items per API page
--cursor <token>
Resume from cursor
--all
Auto-paginate all results
--max-items <n>
Stop after N items
High-Level Async Export
For large jobs, use insights export with --async. This submits an async report run and optionally waits for it to complete and returns the results:
bash
# Submit and wait in one commandagent-adsmetainsightsexport\--accountact_1234567890\--levelad\--fieldsad_id,ad_name,spend,impressions,actions\--since2026-01-01--until2026-03-01\--async--wait# Submit only (returns report_run_id, you poll separately)agent-adsmetainsightsexport\--accountact_1234567890\--levelad\--fieldsad_id,ad_name,spend\--async
Additional flags for async mode:
Flag
Default
Description
--async
off
Use async report run instead of inline query
--wait
off
Poll until complete, then return results (requires --async)
--poll-interval-seconds
5
Seconds between status checks
--wait-timeout-seconds
3600
Maximum wait time before timing out
Without --async, insights export behaves identically to insights query.
--account and --object are mutually exclusive. Use --account for ad-account-level queries, --object for querying a specific campaign/adset/ad.
If you use --action-breakdowns, you must include actions in --fields. The CLI validates this and will error if actions is missing.
Prefer async (--async --wait or explicit report-runs) for large date ranges, ad-level queries across many ads, or heavy breakdown combinations.
--time-increment and --date-preset are separate concepts: --date-preset sets the time range, --time-increment sets how rows are bucketed within that range.
Guide
Meta Creative And Changes
Use this file for inspecting ad creative content and reviewing account activity history.
First command
Meta Creative And Changes
bash
agent-adsmetacreativesget--id120210123456789
Creative Lookups
Get creative by ID
Fetch the full creative object (story spec, asset feed, thumbnail):
# With custom fieldsagent-adsmetacreativesget--id120210123456789--fieldsid,name,body,image_url,call_to_action_type
Preview creative
Get the rendered ad preview. You can target by creative ID or ad ID:
bash
# By creative IDagent-adsmetacreativespreview--creative120210123456789# By ad ID (resolves the ad's creative automatically)agent-adsmetacreativespreview--ad120210987654321
Default fields: body (the rendered preview HTML/payload).
Optional flags:
Flag
Description
--ad-format <format>
Ad format to preview (e.g. DESKTOP_FEED_STANDARD, MOBILE_FEED_STANDARD)
--render-type <type>
Render type (e.g. FALLBACK)
--fields <list>
Custom fields
When using --ad, the CLI first resolves the ad to its creative ID, then calls the preview edge. A warning is emitted noting this resolution step.
Activities (Change History)
List account activity logs to answer "what changed and when?"
Note: pixel-health is a practical diagnostics view built by the CLI. It is not a raw passthrough of Meta's Event Match Quality (EMQ) API. It combines the pixel node metadata with the /stats edge to give a unified health picture.
Guide
Meta Workflows
Use this file for end-to-end recipes. Each workflow is a sequence of commands you can run in order.
First command
Meta Workflows
bash
# Step 1: List all businessesagent-adsmetabusinesseslist--all--pretty# Step 2: For each business, list accessible ad accountsagent-adsmetaad-accountslist--business-id1234567890--scopeaccessible--all# Step 3: Optionally check which accounts you own vs. have access toagent-adsmetaad-accountslist--business-id1234567890--scopeowned--all
1. Multi-Client Account Discovery
Start from your token and discover all businesses and their ad accounts:
bash
# Step 1: List all businessesagent-adsmetabusinesseslist--all--pretty# Step 2: For each business, list accessible ad accountsagent-adsmetaad-accountslist--business-id1234567890--scopeaccessible--all# Step 3: Optionally check which accounts you own vs. have access toagent-adsmetaad-accountslist--business-id1234567890--scopeowned--all
2. Daily Performance Report
Pull daily campaign performance for a date range, exported as CSV:
# Submit the jobagent-adsmetareport-runssubmit\--accountact_1234567890\--levelad\--fieldsad_id,ad_name,spend,impressions,clicks\--since2026-01-01--until2026-03-01# Note the report_run_id from the output, then waitagent-adsmetareport-runswait--id12345678# Fetch resultsagent-adsmetareport-runsresults--id12345678--all--formatcsv--outputresults.csv
5. Forensic Diagnosis
Investigate what changed, inspect the creative, and check pixel health:
bash
# Step 1: What changed in the account recently?agent-adsmetaactivitieslist\--accountact_1234567890\--since2026-03-10T00:00:00Z\--all# Step 2: Inspect a specific ad's creativeagent-adsmetacreativespreview--ad120210987654321# Step 3: Check if the pixel is healthyagent-adsmetapixel-healthget--pixel9876543210# Step 4: Check dataset match qualityagent-adsmetadatasetsget--id5555555555
6. CI/Automation Pattern
Use in scripts or CI jobs with explicit error handling:
bash
#!/bin/bashset-euopipefail# Verify setupagent-adsmetadoctor--api-q# Pull reportagent-adsmetainsightsquery\--accountact_1234567890\--levelcampaign\--fieldscampaign_id,campaign_name,impressions,clicks,spend\--date-presetyesterday\--formatcsv\--output/data/yesterday.csvecho"Report saved to /data/yesterday.csv"
Exit codes make it safe in set -e scripts: 0 = success, 1 = transport/internal, 2 = config/argument, 3 = Meta API error.
7. Piping and Composing
Combine with standard Unix tools:
bash
# Pretty-print to lessagent-adsmetabusinesseslist--pretty|less# Filter with jqagent-adsmetacampaignslist--accountact_1234567890--all|jq'.[] | select(.status == "ACTIVE")'# Count active campaignsagent-adsmetacampaignslist--accountact_1234567890--all|jq'[.[] | select(.effective_status == "ACTIVE")] | length'# JSONL for line-by-line processingagent-adsmetainsightsquery\--accountact_1234567890\--levelcampaign\--fieldscampaign_id,spend\--date-presetlast_7d\--formatjsonl|whileIFS=read-rline;doecho"$line"|jq-r'.campaign_id + ": $" + .spend'done