---
title: meta_create_adset
description: Create a Meta ad set under a campaign, with its audience and its optimization goal. It always arrives paused.
---

Ask for an ad set under a campaign: the countries, the ages, and what delivery optimizes for. AdCrunch creates it paused.

> Add an ad set to Spring Prospecting that targets France and Belgium, ages 25 to 54, and optimizes for purchases on the Northwind Web Pixel.

The agent calls `meta_create_adset`, then [`get_mutation_status`](/mcp/tools/get-mutation-status), and you see the id of the new paused ad set. [Change what runs on Meta](/mcp/tools/change-what-runs-on-meta) walks the whole campaign.

## Reference

**Available on:** [![Meta](/providers/meta.svg)](https://docs.adcrunch.dev/connect/providers)

Create an ad set under a Meta campaign on a live ad account. It is always created PAUSED and cannot be created active. Targeting is countries, an age range, and gender — placements are left to Meta's automatic default. Whether a budget is required depends on the parent campaign: if it uses Advantage campaign budget, the ad set must NOT carry one; otherwise it must. Give `pixelId` and `customEventType` when the optimization goal optimizes toward conversions (find a pixel with `meta_list_pixels`). Runs asynchronously: returns a `workflowId` — call `get_mutation_status` with it to get the new ad set's `id`.

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `advertiserId` | string | yes | Advertiser account ID (`acc_<id>`). Must belong to the active organization. |
| `ageMax` | integer, 13 to 65 | no | Oldest age to target. Omit for no upper bound (Meta treats 65 as 65+). |
| `ageMin` | integer, 13 to 65 | yes | Youngest age to target. Required, not defaulted: many advertisers are obliged to exclude under-18s, and that is not a decision to make on their behalf. Ask the user if you do not know. |
| `campaignId` | string | yes | The Meta ID of the parent campaign — including one you created moments ago, which is fine. |
| `countries` | array of (string, 2 characters), at least 1 item | yes | Two-letter ISO country codes to target, e.g. ["US", "CA"]. |
| `customEventType` | one of `PURCHASE`, `LEAD`, `COMPLETE_REGISTRATION`, `ADD_TO_CART`, `INITIATED_CHECKOUT`, `ADD_PAYMENT_INFO`, `VIEW_CONTENT`, `SEARCH`, `SUBSCRIBE`, `START_TRIAL`, `CONTACT`, `OTHER` | no | Which pixel event to optimize toward, e.g. `PURCHASE`. Required together with `pixelId` for a conversion-optimizing goal. |
| `dailyBudget` | number, more than 0 | no | Daily budget in whole units of the ad account currency (10.5 is 10.50). Provide this or `lifetimeBudget`, not both — and neither if the parent campaign uses Advantage campaign budget. |
| `endTime` | string | no | When delivery should stop, ISO 8601. Required when using `lifetimeBudget`. |
| `genders` | one of `all`, `men`, `women` | no | Who to target. Defaults to everyone. Default: `all`. |
| `lifetimeBudget` | number, more than 0 | no | Lifetime budget in whole units of the ad account currency (10.5 is 10.50). Requires `endTime`. |
| `name` | string, at least 1 character | yes | Ad set name, as it will appear in Ads Manager. |
| `optimizationGoal` | one of `IMPRESSIONS`, `REACH`, `LINK_CLICKS`, `LANDING_PAGE_VIEWS`, `OFFSITE_CONVERSIONS`, `POST_ENGAGEMENT`, `THRUPLAY`, `LEAD_GENERATION`, `VALUE` | yes | What delivery optimizes for. This is a real media-buying decision on the user's money — `LINK_CLICKS` buys clicks, `LANDING_PAGE_VIEWS` buys arrivals, `OFFSITE_CONVERSIONS` buys conversions and needs a pixel. Meta decides which goals are legal under the parent campaign's objective, and will say so if the pairing is not. |
| `pixelId` | string | no | The Meta Pixel to attribute conversions to. Required together with `customEventType` for a conversion-optimizing goal — find one with `meta_list_pixels`. |
| `startTime` | string | no | When delivery should start, ISO 8601. Omit to start as soon as the ad set is activated. |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `workflowId` | string | yes | The id of the change. The change has not reached Meta yet. Give this id to `get_mutation_status` to find out how the change ended. |

### Failure codes

A failed call has `isError` set, and `structuredContent.error` holds one of these codes. [Errors](/mcp/errors) describes the shape of a failed call.

- `not_found`
- `missing_write_access`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `mutation:write`. [Auth & scopes](/mcp/auth) lists each scope.

### Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

- **Writes.** The tool can change data.
- **Destructive.** The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
- **Not idempotent.** A second call with the same arguments can change more.
- **Open world.** The tool reaches a system outside AdCrunch, such as an ad platform.

### Example

The arguments:

```json
{
  "advertiserId": "acc_1485443900032333",
  "ageMax": 54,
  "ageMin": 25,
  "campaignId": "120215678901234567",
  "countries": [
    "FR",
    "BE"
  ],
  "customEventType": "PURCHASE",
  "name": "FR BE 25-54 Purchases",
  "optimizationGoal": "OFFSITE_CONVERSIONS",
  "pixelId": "812345678901234"
}
```

The result, in `structuredContent`:

```json
{
  "workflowId": "3f9c2b7e-8a41-4d6e-9b05-c1e7a2d4f860"
}
```
