> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trycontinuum.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Performance+ ads and optimization

> MCP tools for campaigns, ad sets, ads, audiences, naming, and Paid optimization: inputs, examples, confirmations, and errors.

Generated from the server's own tool registry, as released on 2026-11-05. Every section lists what the tool needs, whether it waits for a yes, how it completes, each action's inputs, valid example calls, and the errors it can return. Before you call a tool, fetch its live schema with `help_describe`; if the server and this page disagree, the server wins.

| Tool | What it does | Changes things |
| - | - | - |
| [`paid_manage`](#paid_manage) | Reads your campaign structure; creates paused campaigns, ad sets, and ads; updates or pauses them; builds audiences and lookalikes; and keeps an audit log of every write. | Yes |
| [`paid_naming_schema_get`](#paid_naming_schema_get) | Your brand's campaign naming convention. | No |
| [`optimizer_query`](#optimizer_query) | Portfolios, pending recommendations, performance, and the optimization log. | No |
| [`optimizer_manage`](#optimizer_manage) | Approves or rejects recommendations and manages portfolios. | Yes |

### `paid_manage`

Reads your campaign structure; creates paused campaigns, ad sets, and ads; updates or pauses them; builds audiences and lookalikes; and keeps an audit log of every write.

**Good to know:**

* Every write is two-phase: `params.mode: "preview"` returns a diff and a `confirm_token` that lasts 10 minutes; repeat the call with `params.mode: "confirm"` and the token.
* Budgets are in minor units of the ad account’s currency: `daily_budget: 1000` is 10.00. Google Ads budgets use micros: `1000000` is 1.00.
* `guardrails` reads the brand’s spend caps for any Viewer; setting them (`mode: "set"`) needs an Admin or Owner.
* Campaigns, ad sets, ads, and copies are created paused. Activating one, raising a budget past the brand's limit (by default, more than 30%), or any write on a brand with an approval chain returns `APPROVAL_REQUIRED` until an Admin or Owner calls `mcp_approval_grant`.
* `batch` previews many writes under one token.
* Each write receipt includes `undo`: the call that reverses it, or null with the reason it can’t be undone.
* `google_ads` runs one Google Ads operation (`update_campaign_budget`, `set_status`, `create_campaign`, `create_ad_group`, or `add_keywords`) with the same preview and confirm steps, and needs the brand’s Google connection. `ENABLED` needs an Admin or Owner.
* Boosting organic posts isn’t supported.

| Contract | Behavior |
| - | - |
| Changes things | Yes |
| Listed in your assistant | Always. |
| Role | Viewer or higher for `hierarchy` and `activity`. Operator or higher for writes. Admin or Owner to set `guardrails`. Activating an ad, or raising a budget past the brand's limit, needs an Admin or Owner's approval. |
| Needs | An active brand. Connection: The one for what you act on: Meta (Facebook), Google. |
| Confirmation | Writes preview first and return a `confirm_token` with `expires_at`. Confirm with that token after the person says yes. |
| Completion | Returns the result in the same call. |
| Retry | Each `confirm_token` works once. Preview again to retry. |
| Rate limit | 60 calls per 1 hour per brand. See [Limits](https://docs.trycontinuum.ai/mcp/reference.md#limits). |

**Actions** (`action`):

| action | Required inputs | Other inputs it uses |
| - | - | - |
| `hierarchy` | `action`, `params`, `params.platform`, `params.ad_account_id`, `params.level` | `params.parent_id`, `params.limit`, `params.cursor`, `params.include_deleted`, `params.include_archived` |
| `create_campaign` | `action`, `params`, `params.platform`, `params.campaign`, `params.mode`, `params.ad_account_id` | `params.adsets`, `params.idempotency_key`, `params.confirm_token` |
| `create_adset` | `action`, `params`, `params.mode`, `params.platform`, `params.ad_account_id`, `params.campaign_id`, `params.adset` | `params.idempotency_key`, `params.confirm_token` |
| `create_ad` | `action`, `params`, `params.mode`, `params.platform`, `params.ad_account_id`, `params.adset_id`, `params.ad` | `params.idempotency_key`, `params.confirm_token` |
| `upload_media` | `action`, `params`, `params.mode`, `params.platform`, `params.ad_account_id` | `params.image_url`, `params.video_url`, `params.asset_id`, `params.idempotency_key`, `params.confirm_token` |
| `update_entity` | `action`, `params`, `params.mode`, `params.platform`, `params.entity_type`, `params.entity_id`, `params.changes` | `params.expected`, `params.idempotency_key`, `params.confirm_token` |
| `update_ad_copy` | `action`, `params`, `params.mode`, `params.platform`, `params.ad_id`, `params.changes` | `params.expected_creative_id`, `params.idempotency_key`, `params.confirm_token` |
| `duplicate` | `action`, `params`, `params.mode`, `params.platform`, `params.entity_type`, `params.entity_id` | `params.deep_copy`, `params.parent_id`, `params.overrides`, `params.idempotency_key`, `params.confirm_token` |
| `create_audience` | `action`, `params`, `params.mode`, `params.ad_account_id`, `params.name`, `params.subtype`, `params.idempotency_key` | `params.pixel_id`, `params.retention_days`, `params.engagement_type`, `params.confirm_token` |
| `create_lookalike` | `action`, `params`, `params.mode`, `params.ad_account_id`, `params.name`, `params.origin_audience_id`, `params.country`, `params.ratio`, `params.lookalike_type`, `params.idempotency_key` | `params.confirm_token` |
| `create_customer_list_audience` | `action`, `params`, `params.mode`, `params.platform`, `params.members` | `params.ad_account_id`, `params.audience_id`, `params.name`, `params.description`, `params.customer_file_source`, `params.default_country_code`, `params.idempotency_key`, `params.confirm_token` |
| `delete_audience` | `action`, `params`, `params.mode`, `params.platform`, `params.audience_id` | `params.idempotency_key`, `params.confirm_token` |
| `send_conversions` | `action`, `params`, `params.mode`, `params.platform`, `params.dataset_id`, `params.events` | `params.default_country_code`, `params.test_event_code`, `params.idempotency_key`, `params.confirm_token` |
| `manage_rules` | `action`, `params`, `params.op` | — |
| `google_ads` | `action`, `params`, `params.op` | — |
| `batch` | `action`, `params`, `params.mode`, `params.ops` | `params.confirm_token` |
| `activity` | `action`, `params` | `params.limit`, `params.tool` |
| `guardrails` | `action`, `params` | — |

**Examples** (IDs are illustrative; use the ones earlier calls return):

* List campaigns: `{"name":"paid_manage","arguments":{"action":"hierarchy","params":{"platform":"meta_ads","ad_account_id":"act_123","level":"campaign"}}}`
* Preview a campaign: `{"name":"paid_manage","arguments":{"action":"create_campaign","params":{"mode":"preview","platform":"meta_ads","ad_account_id":"act_123","campaign":{"name":"Spring","objective":"OUTCOME_TRAFFIC","daily_budget":1000}}}}`
* Cut an ad set to ages 18–55: `{"name":"paid_manage","arguments":{"action":"update_entity","params":{"mode":"preview","platform":"meta_ads","entity_type":"adset","entity_id":"120200000000000000","changes":{"targeting":{"age_max":55}}}}}`
* Restructure in one confirmation: `{"name":"paid_manage","arguments":{"action":"batch","params":{"mode":"preview","ops":[{"action":"duplicate","params":{"platform":"meta_ads","entity_type":"adset","entity_id":"1202…"}},{"action":"update_entity","params":{"platform":"meta_ads","entity_type":"adset","entity_id":"1201…","changes":{"status":"PAUSED"}}}]}}}`
* Audit log: `{"name":"paid_manage","arguments":{"action":"activity","params":{"limit":20}}}`
* Confirm the previewed campaign with its token, after the person says yes: `{"name":"paid_manage","arguments":{"action":"create_campaign","params":{"mode":"confirm","platform":"meta_ads","ad_account_id":"act_123","campaign":{"name":"Spring","objective":"OUTCOME_TRAFFIC","daily_budget":1000},"confirm_token":"tok_7c1e9a2b4d6f8031"}}}`

**Errors and statuses:**

| Code | When |
| - | - |
| `APPROVAL_REQUIRED` | Activating, a budget raise over the brand's spend limits (default +30%) or an approval-chain brand: an admin calls `mcp_approval_grant` with the `confirm_token`, then retry mode='confirm'. |
| `CONFIRMATION_REQUIRED` | Write actions are two-phase: call with params.mode='preview' to get a `confirm_token`, then params.mode='confirm' with that token. |
| `VALIDATION_ERROR` | params is the chosen action's own input. objective must be valid for the platform (e.g. `OUTCOME_*` for `meta_ads`). |
| `CONFLICT` | The item changed or is busy. Read it again, then retry with the current state. |
| `INTEGRATION_DISCONNECTED` | The connection lapsed. Reconnect it with `integrations_connect`. |
| `INTERNAL` | Something went wrong on our side. Retry once, then contact support. |
| `NOT_FOUND` | The item doesn't exist, or this brand can't see it. |
| `UPSTREAM_ERROR` | A platform or provider returned an error. `details` carries its message. |
| `needs_brand` | No brand is active. Call `brands_select`. |
| `needs_role` | The person's role is too low for this call. Needs: Viewer or higher for `hierarchy` and `activity`. Operator or higher for writes. Admin or Owner to set `guardrails`. Activating an ad, or raising a budget past the brand's limit, needs an Admin or Owner's approval. Ask an Admin or Owner. |
| `needs_integration` | The brand lacks the connection this call needs. Call `integrations_connect` with the `platform` the result names. |
| `RATE_LIMITED` | Wait `details.retry_after_seconds`, then retry. |

**Related:** `analytics_query`, `account_map`, `mcp_approval_grant`, `mcp_approvals_list`, `help_describe`.

Full schema: `help_describe {"tool":"paid_manage","action":"hierarchy"}`. As JSON: [`/mcp/schemas/paid_manage.json`](https://docs.trycontinuum.ai/mcp/schemas/paid_manage.json).

### `paid_naming_schema_get`

Your brand's campaign naming convention.

| Contract | Behavior |
| - | - |
| Changes things | No |
| Listed in your assistant | When your role on a brand you can reach allows it. |
| Role | Viewer or higher |
| Needs | An active brand. |
| Confirmation | None. The call runs when made. |
| Completion | Returns the result in the same call. |
| Retry | Safe to retry: it only reads. |

**Inputs:**

| Input | Type | Required | About |
| - | - | - | - |
| `platform` | string | No | The network to act on. See the allowed values. One of `meta`, `google`, `all`. |

**Examples** (IDs are illustrative; use the ones earlier calls return):

* The Meta naming convention: `{"name":"paid_naming_schema_get","arguments":{"platform":"meta"}}`

**Errors and statuses:**

| Code | When |
| - | - |
| `INTERNAL` | Something went wrong on our side. Retry once, then contact support. |
| `BRAND_NOT_SELECTED` | No brand is active. Call `brands_select`. |
| `VALIDATION_ERROR` | An input is missing or wrong, or it changed since the preview. `details` names the field. |

**Related:** `analytics_creative_insights`, `analytics_query`.

Full schema: `help_describe {"tool":"paid_naming_schema_get"}`. As JSON: [`/mcp/schemas/paid_naming_schema_get.json`](https://docs.trycontinuum.ai/mcp/schemas/paid_naming_schema_get.json).

### `optimizer_query`

Portfolios, pending recommendations, performance, and the optimization log.

| Contract | Behavior |
| - | - |
| Changes things | No |
| Listed in your assistant | Always. |
| Role | Viewer or higher, on a brand with a Meta connection. |
| Needs | An active brand. Connection: Meta (Facebook) ads. |
| Confirmation | None. The call runs when made. |
| Completion | Returns the result in the same call. |
| Retry | Safe to retry: it only reads. |

**Actions** (`action`):

| action | Required inputs | Other inputs it uses |
| - | - | - |
| `portfolios` | `action`, `brand_id` | — |
| `logs` | `action`, `brand_id` | — |
| `suggestions` | `action`, `brand_id` | `ad_account_id`, `level` |
| `performance` | `action`, `brand_id`, `portfolio_id` | — |
| `cpa_series` | `action`, `brand_id`, `portfolio_id` | — |
| `angle_matrix` | `action`, `brand_id`, `portfolio_id` | — |
| `pending_recs` | `action`, `brand_id`, `portfolio_id` | — |
| `adsets` | `action`, `brand_id`, `portfolio_id` | — |
| `status` | `action`, `brand_id`, `portfolio_id` | — |
| `insight` | `action`, `brand_id`, `payload` | — |
| `renewal_tasks` | `action`, `brand_id` | `status` |

**Examples** (IDs are illustrative; use the ones earlier calls return):

* A portfolio's pending recommendations: `{"name":"optimizer_query","arguments":{"action":"pending_recs","brand_id":"5c8e1a3b-7d2f-4e6a-9b4c-0f1e3d5a7c92","portfolio_id":"3f6b2c1e-8a4d-4f7b-9c2e-1d5a7b9e0c43"}}`

**Errors and statuses:**

| Code | When |
| - | - |
| `VALIDATION_ERROR` | An input is missing or wrong, or it changed since the preview. `details` names the field. |
| `needs_brand` | No brand is active. Call `brands_select`. |
| `needs_integration` | The brand lacks the connection this call needs. Call `integrations_connect` with the `platform` the result names. |

**Related:** `help_describe`, `optimizer_manage`.

Full schema: `help_describe {"tool":"optimizer_query","action":"portfolios"}`. As JSON: [`/mcp/schemas/optimizer_query.json`](https://docs.trycontinuum.ai/mcp/schemas/optimizer_query.json).

### `optimizer_manage`

Approves or rejects recommendations and manages portfolios.

| Contract | Behavior |
| - | - |
| Changes things | Yes |
| Listed in your assistant | Always. |
| Role | Operator or higher, on a brand with a Meta connection. |
| Needs | An active brand. Connection: Meta (Facebook) ads. |
| Confirmation | Writes preview first and return a `confirm_token` with `expires_at`. Confirm with that token after the person says yes. |
| Completion | Returns the result in the same call. |
| Retry | Not idempotent. Check the current state before retrying. |

**Actions** (`action`):

| action | Required inputs | Other inputs it uses |
| - | - | - |
| `create_portfolio` | `action`, `payload` | — |
| `create_from_suggestion` | `action`, `payload` | — |
| `enroll_adsets` | `action`, `payload` | — |
| `convert_cbo` | `action`, `payload` | — |
| `set_recommendation_status` | `action`, `payload` | — |
| `set_recommendation_statuses` | `action`, `payload` | — |
| `set_renewal_task_status` | `action`, `payload` | — |
| `update_portfolio` | `action`, `payload` | — |
| `archive_portfolio` | `action`, `payload` | — |
| `unenroll_adsets` | `action`, `payload` | — |
| `run_now` | `action`, `payload` | — |

**Examples** (IDs are illustrative; use the ones earlier calls return):

* Approve one recommendation (the approval is the yes): `{"name":"optimizer_manage","arguments":{"action":"set_recommendation_status","payload":{"portfolio_id":"3f6b2c1e-8a4d-4f7b-9c2e-1d5a7b9e0c43","recommendation_id":"9a1d4e7c-2b6f-4c8a-b3e5-7f0d2a6c9b18","status":"approved"}}}`

**Errors and statuses:**

| Code | When |
| - | - |
| `BRAND_FORBIDDEN` | The person can't reach that brand. |
| `CONFIRMATION_REQUIRED` | This write needs a preview first. Preview, get a yes, then confirm with the returned token. |
| `CONFLICT` | The item changed or is busy. Read it again, then retry with the current state. |
| `INTERNAL` | Something went wrong on our side. Retry once, then contact support. |
| `NOT_FOUND` | The item doesn't exist, or this brand can't see it. |
| `PERMISSION_DENIED` | The person's role can't do this. Ask an Admin or Owner. |
| `needs_brand` | No brand is active. Call `brands_select`. |
| `needs_role` | The person's role is too low for this call. Needs: Operator or higher, on a brand with a Meta connection. Ask an Admin or Owner. |
| `needs_integration` | The brand lacks the connection this call needs. Call `integrations_connect` with the `platform` the result names. |
| `VALIDATION_ERROR` | An input is missing or wrong, or it changed since the preview. `details` names the field. |

**Related:** `help_describe`, `mcp_approval_grant`, `optimizer_query`, `paid_manage`.

Full schema: `help_describe {"tool":"optimizer_manage","action":"create_portfolio"}`. As JSON: [`/mcp/schemas/optimizer_manage.json`](https://docs.trycontinuum.ai/mcp/schemas/optimizer_manage.json).

## What's next

* [All tools](https://docs.trycontinuum.ai/mcp/tools.md): Every tool on one page, and the machine-readable index.
* [Account, brand, and jobs](https://docs.trycontinuum.ai/mcp/tools/account.md): Lists the brands you can access, and more.
* [Analytics, trends, and competitors](https://docs.trycontinuum.ai/mcp/tools/insights.md): Organic, paid, and website results by platform: accounts, top posts, campaigns, ad sets, and ads, and more.
* [Organic+ planning and publishing](https://docs.trycontinuum.ai/mcp/tools/organic.md): Reads and proposes a week of posts, approves it, reschedules and copies posts, and attaches media, and more.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.