create_campaign
Build and launch Meta Ads campaigns by specifying account details, objectives, budgets, bid strategies, and A/B testing configurations directly through the Meta Ads MCP server.
Instructions
Create a new campaign in a Meta Ads account.
Args:
access_token: Meta API access token (optional - will use cached token if not provided)
account_id: Meta Ads account ID (format: act_XXXXXXXXX)
name: Campaign name
objective: Campaign objective (ODAX, outcome-based). Must be one of:
OUTCOME_AWARENESS, OUTCOME_TRAFFIC, OUTCOME_ENGAGEMENT,
OUTCOME_LEADS, OUTCOME_SALES, OUTCOME_APP_PROMOTION.
Note: Legacy objectives like BRAND_AWARENESS, LINK_CLICKS,
CONVERSIONS, APP_INSTALLS, etc. are not valid for new
campaigns and will cause a 400 error. Use the outcome-based
values above (e.g., BRAND_AWARENESS → OUTCOME_AWARENESS).
status: Initial campaign status (default: PAUSED)
special_ad_categories: List of special ad categories if applicable
daily_budget: Daily budget in account currency (in cents) as a string (only used if use_adset_level_budgets=False)
lifetime_budget: Lifetime budget in account currency (in cents) as a string (only used if use_adset_level_budgets=False)
buying_type: Buying type (e.g., 'AUCTION')
bid_strategy: Bid strategy. Must be one of: 'LOWEST_COST_WITHOUT_CAP', 'LOWEST_COST_WITH_BID_CAP', 'COST_CAP', 'LOWEST_COST_WITH_MIN_ROAS'.
bid_cap: Bid cap in account currency (in cents) as a string
spend_cap: Spending limit for the campaign in account currency (in cents) as a string
campaign_budget_optimization: Whether to enable campaign budget optimization (only used if use_adset_level_budgets=False)
ab_test_control_setups: Settings for A/B testing (e.g., [{"name":"Creative A", "ad_format":"SINGLE_IMAGE"}])
use_adset_level_budgets: If True, budgets will be set at the ad set level instead of campaign level (default: False)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ab_test_control_setups | No | ||
| access_token | No | ||
| account_id | No | ||
| bid_cap | No | ||
| bid_strategy | No | ||
| buying_type | No | ||
| campaign_budget_optimization | No | ||
| daily_budget | No | ||
| lifetime_budget | No | ||
| name | No | ||
| objective | No | ||
| special_ad_categories | No | ||
| spend_cap | No | ||
| status | No | PAUSED | |
| use_adset_level_budgets | No |
Input Schema (JSON Schema)
{
"properties": {
"ab_test_control_setups": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Ab Test Control Setups"
},
"access_token": {
"default": null,
"title": "Access Token",
"type": "string"
},
"account_id": {
"default": null,
"title": "Account Id",
"type": "string"
},
"bid_cap": {
"default": null,
"title": "bid_cap",
"type": "string"
},
"bid_strategy": {
"default": null,
"title": "Bid Strategy",
"type": "string"
},
"buying_type": {
"default": null,
"title": "Buying Type",
"type": "string"
},
"campaign_budget_optimization": {
"default": null,
"title": "Campaign Budget Optimization",
"type": "boolean"
},
"daily_budget": {
"default": null,
"title": "daily_budget",
"type": "string"
},
"lifetime_budget": {
"default": null,
"title": "lifetime_budget",
"type": "string"
},
"name": {
"default": null,
"title": "Name",
"type": "string"
},
"objective": {
"default": null,
"title": "Objective",
"type": "string"
},
"special_ad_categories": {
"default": null,
"items": {
"type": "string"
},
"title": "Special Ad Categories",
"type": "array"
},
"spend_cap": {
"default": null,
"title": "spend_cap",
"type": "string"
},
"status": {
"default": "PAUSED",
"title": "Status",
"type": "string"
},
"use_adset_level_budgets": {
"default": false,
"title": "Use Adset Level Budgets",
"type": "boolean"
}
},
"title": "create_campaignArguments",
"type": "object"
}
Implementation Reference
- meta_ads_mcp/core/campaigns.py:114-230 (handler)The core handler function decorated as an MCP tool that implements the create_campaign logic by making a POST request to the Meta Ads API to create a new campaign.@mcp_server.tool() @meta_api_tool async def create_campaign( account_id: str, name: str, objective: str, access_token: Optional[str] = None, status: str = "PAUSED", special_ad_categories: Optional[List[str]] = None, daily_budget: Optional[int] = None, lifetime_budget: Optional[int] = None, buying_type: Optional[str] = None, bid_strategy: Optional[str] = None, bid_cap: Optional[int] = None, spend_cap: Optional[int] = None, campaign_budget_optimization: Optional[bool] = None, ab_test_control_setups: Optional[List[Dict[str, Any]]] = None, use_adset_level_budgets: bool = False ) -> str: """ Create a new campaign in a Meta Ads account. Args: account_id: Meta Ads account ID (format: act_XXXXXXXXX) name: Campaign name objective: Campaign objective (ODAX, outcome-based). Must be one of: OUTCOME_AWARENESS, OUTCOME_TRAFFIC, OUTCOME_ENGAGEMENT, OUTCOME_LEADS, OUTCOME_SALES, OUTCOME_APP_PROMOTION. Note: Legacy objectives like BRAND_AWARENESS, LINK_CLICKS, CONVERSIONS, APP_INSTALLS, etc. are not valid for new campaigns and will cause a 400 error. Use the outcome-based values above (e.g., BRAND_AWARENESS → OUTCOME_AWARENESS). access_token: Meta API access token (optional - will use cached token if not provided) status: Initial campaign status (default: PAUSED) special_ad_categories: List of special ad categories if applicable daily_budget: Daily budget in account currency (in cents) as a string (only used if use_adset_level_budgets=False) lifetime_budget: Lifetime budget in account currency (in cents) as a string (only used if use_adset_level_budgets=False) buying_type: Buying type (e.g., 'AUCTION') bid_strategy: Bid strategy. Must be one of: 'LOWEST_COST_WITHOUT_CAP', 'LOWEST_COST_WITH_BID_CAP', 'COST_CAP', 'LOWEST_COST_WITH_MIN_ROAS'. bid_cap: Bid cap in account currency (in cents) as a string spend_cap: Spending limit for the campaign in account currency (in cents) as a string campaign_budget_optimization: Whether to enable campaign budget optimization (only used if use_adset_level_budgets=False) ab_test_control_setups: Settings for A/B testing (e.g., [{"name":"Creative A", "ad_format":"SINGLE_IMAGE"}]) use_adset_level_budgets: If True, budgets will be set at the ad set level instead of campaign level (default: False) """ # Check required parameters if not account_id: return json.dumps({"error": "No account ID provided"}, indent=2) if not name: return json.dumps({"error": "No campaign name provided"}, indent=2) if not objective: return json.dumps({"error": "No campaign objective provided"}, indent=2) # Special_ad_categories is required by the API, set default if not provided if special_ad_categories is None: special_ad_categories = [] # For this example, we'll add a fixed daily budget if none is provided and we're not using ad set level budgets if not daily_budget and not lifetime_budget and not use_adset_level_budgets: daily_budget = "1000" # Default to $10 USD endpoint = f"{account_id}/campaigns" params = { "name": name, "objective": objective, "status": status, "special_ad_categories": json.dumps(special_ad_categories) # Properly format as JSON string } # Only set campaign-level budgets if we're not using ad set level budgets if not use_adset_level_budgets: # Convert budget values to strings if they aren't already if daily_budget is not None: params["daily_budget"] = str(daily_budget) if lifetime_budget is not None: params["lifetime_budget"] = str(lifetime_budget) if campaign_budget_optimization is not None: params["campaign_budget_optimization"] = "true" if campaign_budget_optimization else "false" # Add new parameters if buying_type: params["buying_type"] = buying_type if bid_strategy: params["bid_strategy"] = bid_strategy if bid_cap is not None: params["bid_cap"] = str(bid_cap) if spend_cap is not None: params["spend_cap"] = str(spend_cap) if ab_test_control_setups: params["ab_test_control_setups"] = json.dumps(ab_test_control_setups) try: data = await make_api_request(endpoint, access_token, params, method="POST") # Add a note about budget strategy if using ad set level budgets if use_adset_level_budgets: data["budget_strategy"] = "ad_set_level" data["note"] = "Campaign created with ad set level budgets. Set budgets when creating ad sets within this campaign." return json.dumps(data, indent=2) except Exception as e: error_msg = str(e) return json.dumps({ "error": "Failed to create campaign", "details": error_msg, "params_sent": params }, indent=2)