create_adset
Create a new ad set under a campaign. Define targeting, optimization goal, billing event, and budget. Ad set is paused by default. Enable dynamic creative for multi-text formats.
Instructions
WRITE: Create an ad set under a campaign. Default status is PAUSED. targeting is a Meta targeting spec object (geo_locations, age_min, age_max, interests, etc.). bid_amount is in account currency minor units (cents). For multi-text / dynamic creative ads you MUST set is_dynamic_creative=true — otherwise asset_feed_spec ads will be rejected.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ad_account_id | Yes | 'act_123' or '123' | |
| campaign_id | Yes | ||
| name | Yes | ||
| targeting | Yes | Meta targeting spec object (JSON) | |
| optimization_goal | Yes | e.g. OFFSITE_CONVERSIONS | |
| billing_event | Yes | ||
| bid_amount | No | Bid in minor currency units (cents). Always set at adset level. | |
| daily_budget | No | For ABO; omit under CBO | |
| lifetime_budget | No | ||
| start_time | No | ISO 8601, e.g. '2026-01-15T00:00:00+0000' | |
| end_time | No | ||
| status | No | ||
| is_dynamic_creative | No | Must be true for asset_feed_spec / multi-text creatives | |
| promoted_object | No | e.g. {pixel_id: 'XXX', custom_event_type: 'PURCHASE'} for conversion optimization | |
| pacing_type | No | e.g. ['standard'] or ['no_pacing'] |
Implementation Reference
- src/tools/adsets.ts:138-161 (handler)The async handler function that executes the create_adset tool logic. It constructs a body with required fields (campaign_id, name, targeting, optimization_goal, billing_event, status defaulting to PAUSED), conditionally adds optional fields (bid_amount, daily_budget, lifetime_budget, start_time, end_time, is_dynamic_creative, promoted_object, pacing_type), and POSTs to /{ad_account_id}/adsets via metaPost.
handler: async (args) => { const body: Record<string, unknown> = { campaign_id: args.campaign_id, name: args.name, targeting: args.targeting, optimization_goal: args.optimization_goal, billing_event: args.billing_event, status: args.status ?? "PAUSED", }; if (args.bid_amount !== undefined) body.bid_amount = args.bid_amount; if (args.daily_budget !== undefined) body.daily_budget = args.daily_budget; if (args.lifetime_budget !== undefined) body.lifetime_budget = args.lifetime_budget; if (args.start_time) body.start_time = args.start_time; if (args.end_time) body.end_time = args.end_time; if (args.is_dynamic_creative !== undefined) body.is_dynamic_creative = args.is_dynamic_creative; if (args.promoted_object) body.promoted_object = args.promoted_object; if (args.pacing_type) body.pacing_type = args.pacing_type; return metaPost( `/${toAdAccountPath(String(args.ad_account_id))}/adsets`, body, ); }, }, - src/tools/adsets.ts:97-137 (schema)The inputSchema for create_adset, using Zod validators. Defines required fields (ad_account_id, campaign_id, name, targeting, optimization_goal, billing_event) and optional fields (bid_amount, daily_budget, lifetime_budget, start_time, end_time, status, is_dynamic_creative, promoted_object, pacing_type). References OPTIMIZATION_GOAL and BILLING_EVENT enum schemas.
inputSchema: { ad_account_id: z.string().describe("'act_123' or '123'"), campaign_id: z.string(), name: z.string().min(1), targeting: z.record(z.unknown()).describe("Meta targeting spec object (JSON)"), optimization_goal: OPTIMIZATION_GOAL.describe("e.g. OFFSITE_CONVERSIONS"), billing_event: BILLING_EVENT, bid_amount: z .number() .int() .positive() .optional() .describe("Bid in minor currency units (cents). Always set at adset level."), daily_budget: z .number() .int() .positive() .optional() .describe("For ABO; omit under CBO"), lifetime_budget: z.number().int().positive().optional(), start_time: z .string() .optional() .describe("ISO 8601, e.g. '2026-01-15T00:00:00+0000'"), end_time: z.string().optional(), status: STATUS.optional(), is_dynamic_creative: z .boolean() .optional() .describe("Must be true for asset_feed_spec / multi-text creatives"), promoted_object: z .record(z.unknown()) .optional() .describe( "e.g. {pixel_id: 'XXX', custom_event_type: 'PURCHASE'} for conversion optimization", ), pacing_type: z .array(z.string()) .optional() .describe("e.g. ['standard'] or ['no_pacing']"), }, - src/tools/adsets.ts:15-29 (schema)The OPTIMIZATION_GOAL Zod enum schema used by create_adset's inputSchema, defining valid optimization goals like NONE, LINK_CLICKS, OFFSITE_CONVERSIONS, etc.
const OPTIMIZATION_GOAL = z.enum([ "NONE", "LINK_CLICKS", "IMPRESSIONS", "REACH", "OFFSITE_CONVERSIONS", "LEAD_GENERATION", "LANDING_PAGE_VIEWS", "THRUPLAY", "VIDEO_VIEWS", "APP_INSTALLS", "POST_ENGAGEMENT", "QUALITY_LEAD", "VALUE", ]); - src/tools/adsets.ts:31-37 (schema)The BILLING_EVENT Zod enum schema used by create_adset's inputSchema, defining valid billing events (IMPRESSIONS, LINK_CLICKS, THRUPLAY, POST_ENGAGEMENT, APP_INSTALLS).
const BILLING_EVENT = z.enum([ "IMPRESSIONS", "LINK_CLICKS", "THRUPLAY", "POST_ENGAGEMENT", "APP_INSTALLS", ]); - src/index.ts:47-57 (registration)The create_adset tool is registered via the adsetTools array which is spread into allTools and then each tool is registered via server.registerTool() with its name, description, inputSchema, and handler.
const allTools: ToolDef[] = [ ...accountTools, ...campaignTools, ...adsetTools, ...adTools, ...creativeTools, ...mediaTools, ...insightsTools, ...bulkTools, ...pageTools, ...adsLibraryTools,