# Meta Ads Agency Setup Guide

## Overview

To run ads for multiple clients from a single account, you need a **Meta Business Manager** configured as an agency with a **System User** token.

## Step-by-Step Setup

### 1. Create Business Manager

1. Go to [business.facebook.com/overview](https://business.facebook.com/overview)
2. Click "Create Account"
3. Enter your business name, your name, and business email
4. This is your **agency Business Manager** — it can manage multiple client ad accounts

### 2. Create a Facebook Page (if needed)

Ads must be associated with a Facebook Page.

1. In Business Manager → Business Settings → Accounts → Pages
2. Click "Add" → "Create a New Page"
3. Or use an existing page — click "Add" → "Add a Page"
4. Note the **Page ID** (visible in the Page's About section or URL)

### 3. Create Meta App

1. Go to [developers.facebook.com/apps](https://developers.facebook.com/apps)
2. Click "Create App" → Select "Other" → "Business"
3. Connect it to your Business Manager
4. In the app dashboard, add the **Marketing API** product
5. Note your **App ID** and **App Secret**

### 4. Create System User + Token

System Users are non-human identities for API access. More stable than user tokens.

1. Business Manager → Business Settings → System Users
2. Click "Add" → name it (e.g., "Zo Ads Bot") → Role: **Admin**
3. Click "Generate Token"
4. Select your Meta App
5. Grant these permissions:
   - `ads_management` — create/edit campaigns
   - `ads_read` — read campaign data
   - `business_management` — manage business assets
   - `pages_read_engagement` — use pages for ads
6. Set token expiration to **Never** (or manage rotation)
7. Copy the token immediately — it won't be shown again

### 5. Save Secrets in Zo

Go to [Settings > Advanced](/?t=settings&s=advanced) and add:

| Secret Name | Value | Example |
|---|---|---|
| `META_ACCESS_TOKEN` | System User token | `EAAG...` (long string) |
| `META_AD_ACCOUNT_ID` | Default ad account | `act_123456789` |
| `META_PAGE_ID` | Facebook Page ID | `109876543210` |

### 6. Multi-Client: Granting Access

For each new client:

#### Option A: Client grants partner access (preferred)
1. Client goes to their Business Manager → Business Settings → Ad Accounts
2. Click the ad account → Partners → Add
3. Enter your Business Manager ID (found in Business Settings → Business Info)
4. Grant "Manage campaigns" permission

#### Option B: Create ad account under your BM
1. Your Business Manager → Ad Accounts → Add → Create New
2. Set the client's billing (their payment method)
3. You own and manage the account

### 7. Test the Setup

```bash
# Verify token works
curl -s "https://graph.facebook.com/v21.0/me?access_token=$META_ACCESS_TOKEN" | jq .

# List ad accounts accessible to this token
curl -s "https://graph.facebook.com/v21.0/me/adaccounts?access_token=$META_ACCESS_TOKEN&fields=name,account_id,account_status" | jq .

# Check a specific ad account
curl -s "https://graph.facebook.com/v21.0/$META_AD_ACCOUNT_ID?access_token=$META_ACCESS_TOKEN&fields=name,currency,spend_cap" | jq .
```

## Rate Limits

- Marketing API has tiered rate limits based on app review status
- Standard: 200 calls/hour per ad account
- After app review (recommended for production): much higher
- The recon script batches API calls to stay well under limits

## Troubleshooting

| Error | Cause | Fix |
|---|---|---|
| `OAuthException (code 190)` | Token expired/invalid | Regenerate System User token |
| `OAuthException (code 10)` | Missing permission | Re-grant required scopes |
| `Error code 1487301` | Ad account not accessible | Check partner access was granted |
| `Error code 100, invalid parameter` | Wrong ad account format | Must be `act_XXXXXXXXX` |

## Security Notes

- System User tokens have no expiry by default — rotate periodically anyway
- Limit token scopes to only what's needed
- Each client relationship should be documented
- Campaign logs include ad account IDs for audit trail
