create_meta_campaign
Create a complete Meta (Facebook/Instagram) ad campaign with targeting, creative, and budget in one call. Campaigns are created paused for review before activation.
Instructions
Create a complete Meta (Facebook/Instagram) ad campaign in one call — campaign + ad set with targeting + creative + ad. Created in PAUSED state. Call enable_meta_campaign to activate. Minimum budget $1/day. Requires Starter plan or higher.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Campaign name. Example: "Spring Sale — Traffic — US" | |
| objective | No | Objective: OUTCOME_TRAFFIC, OUTCOME_LEADS, OUTCOME_SALES, OUTCOME_ENGAGEMENT, OUTCOME_AWARENESS. Default: OUTCOME_TRAFFIC | |
| daily_budget_usd | Yes | Daily spend limit in USD. Minimum: 1. | |
| destination_url | Yes | Full URL (including https://) users land on after clicking. | |
| ad_headline | Yes | Bold ad headline. Max 40 characters. | |
| ad_body | Yes | Main ad copy. Max 125 characters. | |
| targeting_countries | No | Country codes. Example: ["US","CA","GB"]. Default: ["US"]. | |
| age_min | No | Minimum target age. Default: 18. | |
| age_max | No | Maximum target age. Default: 65. |
Implementation Reference
- src/index.ts:427-483 (handler)The handler logic for creating a Meta campaign, which creates the campaign, ad set, creative, and ad in a sequence.
case 'create_meta_campaign': { const denied = licenseCheck('meta'); if (denied) return fail(denied); if (!cfg.hasMeta()) return fail('Meta credentials not set.'); if (!cfg.metaPage()) return fail('META_PAGE_ID required to create ads.'); if (!args.name || !args.daily_budget_usd || !args.destination_url || !args.ad_headline || !args.ad_body) return fail('Required: name, daily_budget_usd, destination_url, ad_headline, ad_body'); // Validate budget const budgetError = validateMetaBudget(args.daily_budget_usd); if (budgetError) return fail(budgetError); // Validate URL const urlError = validateUrl(args.destination_url); if (urlError) return fail(urlError); const campaignRes = await metaPost(`/${cfg.metaAccount()}/campaigns`, { name: args.name, objective: args.objective || 'OUTCOME_TRAFFIC', status: 'PAUSED', special_ad_categories: [], }); const adSetRes = await metaPost(`/${cfg.metaAccount()}/adsets`, { name: `${args.name} — Ad Set`, campaign_id: campaignRes.id, daily_budget: Math.round((args.daily_budget_usd as number) * 100), billing_event: 'IMPRESSIONS', optimization_goal: 'LINK_CLICKS', targeting: { geo_locations: { countries: (args.targeting_countries as string[]) || ['US'] }, age_min: (args.age_min as number) || 18, age_max: (args.age_max as number) || 65, }, status: 'PAUSED', }); const creativeRes = await metaPost(`/${cfg.metaAccount()}/adcreatives`, { name: `${args.name} — Creative`, object_story_spec: { page_id: cfg.metaPage(), link_data: { message: args.ad_body, link: args.destination_url, name: args.ad_headline, call_to_action: { type: 'LEARN_MORE', value: { link: args.destination_url } }, }, }, }); const adRes = await metaPost(`/${cfg.metaAccount()}/ads`, { name: `${args.name} — Ad`, adset_id: adSetRes.id, creative: { creative_id: creativeRes.id }, status: 'PAUSED', }); return ok({ success: true, status: 'PAUSED', next_step: 'Call enable_meta_campaign with campaign_id to start running.', campaign_id: campaignRes.id, adset_id: adSetRes.id, creative_id: creativeRes.id, ad_id: adRes.id, daily_budget_usd: args.daily_budget_usd, }); } - src/index.ts:226-243 (schema)The tool registration and schema definition for 'create_meta_campaign' within the TOOLS array.
name: 'create_meta_campaign', description: 'Create a complete Meta (Facebook/Instagram) ad campaign in one call — campaign + ad set with targeting + creative + ad. Created in PAUSED state. Call enable_meta_campaign to activate. Minimum budget $1/day. Requires Starter plan or higher.', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Campaign name. Example: "Spring Sale — Traffic — US"' }, objective: { type: 'string', description: 'Objective: OUTCOME_TRAFFIC, OUTCOME_LEADS, OUTCOME_SALES, OUTCOME_ENGAGEMENT, OUTCOME_AWARENESS. Default: OUTCOME_TRAFFIC' }, daily_budget_usd: { type: 'number', description: 'Daily spend limit in USD. Minimum: 1.' }, destination_url: { type: 'string', description: 'Full URL (including https://) users land on after clicking.' }, ad_headline: { type: 'string', description: 'Bold ad headline. Max 40 characters.' }, ad_body: { type: 'string', description: 'Main ad copy. Max 125 characters.' }, targeting_countries: { type: 'array', items: { type: 'string' }, description: 'Country codes. Example: ["US","CA","GB"]. Default: ["US"].' }, age_min: { type: 'number', description: 'Minimum target age. Default: 18.' }, age_max: { type: 'number', description: 'Maximum target age. Default: 65.' }, }, required: ['name', 'daily_budget_usd', 'destination_url', 'ad_headline', 'ad_body'], }, },