Skip to main content
Glama

create_campaign

Create new Meta advertising campaigns with outcome-based objectives, budget controls, and bid strategies to manage Facebook and Instagram ads.

Instructions

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)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
account_idYes
nameYes
objectiveYes
access_tokenNo
statusNoPAUSED
special_ad_categoriesNo
daily_budgetNo
lifetime_budgetNo
buying_typeNo
bid_strategyNo
bid_capNo
spend_capNo
campaign_budget_optimizationNo
ab_test_control_setupsNo
use_adset_level_budgetsNo

Implementation Reference

  • The primary handler for the 'create_campaign' tool. This function defines the tool's parameters with type annotations and docstring describing inputs/outputs, validates inputs, constructs API parameters (handling budgets, special categories as JSON, etc.), and performs a POST request to the Meta Ads API endpoint /{account_id}/campaigns using make_api_request. Decorators @mcp_server.tool() and @meta_api_tool register it as an MCP tool.
    @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)
  • Registers 'create_campaign' by importing it from campaigns.py into the core package namespace, allowing it to be used and further exported.
    from .campaigns import get_campaigns, get_campaign_details, create_campaign
  • Re-exports 'create_campaign' from core package into the top-level meta_ads_mcp package namespace via import, making it available for use.
    create_campaign,
  • Includes 'create_campaign' in core.__all__, explicitly registering it for import from the core package (from meta_ads_mcp.core import create_campaign).
    'create_campaign',

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pipeboard-co/meta-ads-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server