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

# Update Meta Ad Set

> User wants to edit an existing Meta ad set's targeting, budget, bid, placements, schedule, or optimization settings.

IMPORTANT: This tool modifies REAL ad sets in Meta Ads Manager. Changes take effect immediately.

This is the primary tool for:
- Changing audience targeting (age, gender, interests, locations)
- Excluding placements (e.g., remove Audience Network)
- Adjusting budgets at the ad set level
- Changing bid amounts
- Pausing/resuming specific ad sets
- Modifying optimization goals

Returns:
- Confirmation of updates applied
- Summary of all changes made
- Ads Manager URL for the ad set

When to use this tool:
- "Change the targeting on my ad set"
- "Exclude Audience Network from placements"
- "Update the budget on this ad set to $50/day"
- "Pause this ad set"
- "Change the age range to 25-45"
- "Add interest targeting for fitness"
- "Exclude custom audience from this ad set"
- "Change bid to $5"
- "Update the optimization goal"

Parameters:
- ad_set_id: The Meta Ad Set ID to update (required)
- status: ACTIVE, PAUSED, DELETED, ARCHIVED (optional)
- name: New ad set name (optional)
- daily_budget: New daily budget in USD (optional, min $1). DO NOT use for CBO campaigns.
- lifetime_budget: New lifetime budget in USD (optional). DO NOT use for CBO campaigns.
- daily_min_spend_target: CBO only — minimum daily spend for this ad set (use INSTEAD of daily_budget)
- daily_spend_cap: CBO only — maximum daily spend cap for this ad set (use INSTEAD of daily_budget)
- lifetime_min_spend_target: CBO only — minimum lifetime spend (for lifetime budget CBO)
- lifetime_spend_cap: CBO only — maximum lifetime spend cap (for lifetime budget CBO)
- bid_amount: New bid amount in USD (optional)
- targeting: New targeting spec as JSON (optional) — for placements, audiences, demographics
- start_time: New start time ISO format (optional)
- end_time: New end time ISO format (optional)
- optimization_goal: REACH, LINK_CLICKS, LANDING_PAGE_VIEWS, OFFSITE_CONVERSIONS, VALUE, etc. (optional)

**CBO (Advantage Campaign Budget) campaigns:**
For ad sets under CBO campaigns, do NOT set daily_budget or lifetime_budget.
Use daily_min_spend_target / daily_spend_cap to control spend distribution.
Setting daily_budget on a CBO ad set will cause Meta to reject with an error.

At least one update field must be provided.

Targeting Spec Examples:

*Exclude Audience Network:*
```json
{
  "publisher_platforms": ["facebook", "instagram"],
  "facebook_positions": ["feed", "stories", "reels"],
  "instagram_positions": ["stream", "story", "reels"]
}
```

*Change age and gender:*
```json
{
  "age_min": 25,
  "age_max": 45,
  "genders": [1]
}
```
(genders: 1=male, 2=female, omit for all)

*Add interest targeting:*
```json
{
  "flexible_spec": [{"interests": [{"id": "6003139266461", "name": "Fitness"}]}]
}
```

*Exclude custom audience:*
```json
{
  "excluded_custom_audiences": [{"id": "AUDIENCE_ID"}]
}
```

Execution time: 2-5 seconds
Modifies: Real ad set in Meta Ads

Workflow:
1. Use `list_meta_ad_sets` or `get_meta_campaign_details` to find the ad set ID
2. Use `update_meta_ad_set` with the changes you want to make
3. Verify changes in Ads Manager



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/tools/update_meta_ad_set/execute
openapi: 3.1.0
info:
  contact:
    email: support@adspirer.com
    name: Adspirer Support
  description: >-
    REST endpoints for every Adspirer tool. Same surface as the MCP server, over
    plain HTTP for consumers that can't speak SSE (n8n, Zapier, Make, curl, any
    language's HTTP client).


    ## Envelope

    Every request wraps tool-specific input in an `arguments` object:

    ```json

    { "arguments": { <tool-specific fields> } }

    ```

    Every response wraps the result in either a success envelope (`success:
    true`, `data: {...}`) or an error envelope (`success: false`, `error:
    "..."`, `is_error: true`).


    ## Authentication

    Pass your API key as `Authorization: Bearer sk_live_...` on every request.
    Generate keys at https://adspirer.ai/keys.


    ## Quota & billing

    Every successful billable call decrements your monthly tool-call allowance.
    The current counter is attached to every 200 response under `data.quota`:

    ```json

    "quota": { "used": 42, "limit": 150, "tier": "plus", "period_end":
    "2026-05-01" }

    ```

    When the limit is hit, the API returns HTTP 402 with a full `quota` block
    including `upgrade_url`. Read-only diagnostic tools (`get_usage_status`,
    `list_connected_accounts`, `get_connections_status`) are exempt and never
    consume quota.


    ## Idempotency

    Write operations accept an `Idempotency-Key: <uuid>` header. A repeated call
    with the same key returns the cached result rather than executing twice.
    **Strongly recommended for n8n, Zapier, and any retry-prone client** — it
    prevents duplicate campaigns when networks misbehave. Generate a fresh UUID
    per logical operation (not per retry).


    ## Multi-account users

    Customers with multiple connected accounts on the same platform (e.g. an
    agency with 10 Meta ad accounts) must specify which account to use via
    `ad_account_id`, `customer_id`, `advertiser_id`, or `account_id` depending
    on the platform. Omitting it returns HTTP 400 with a list of valid account
    IDs. See `list_connected_accounts` to discover available IDs.


    ## HTTP status codes

    - `200` — success (parse `data`)

    - `400` — tool-level error (surface `error` to users)

    - `401` — bad/missing API key

    - `402` — Adspirer quota exhausted

    - `404` — unknown tool name

    - `429` — upstream ad platform rate-limited us (Meta/Google/etc.) — retry
    with backoff

    - `500` — server error, report to support


    ## Streaming

    This endpoint is plain request-response JSON. There is **no SSE, no chunked
    streaming**. Safe to use from n8n Cloud's HTTP Request node, Zapier
    Webhooks, Make HTTP module, curl, and every mainstream HTTP library.
  title: Adspirer REST API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.adspirer.ai
security: []
tags:
  - description: Audit tools
    name: audit
  - description: General (Account Management) tools
    name: general
  - description: Google Ads tools
    name: google-ads
  - description: LinkedIn Ads tools
    name: linkedin-ads
  - description: Meta Ads tools
    name: meta-ads
  - description: Monitoring & Reporting tools
    name: monitoring
  - description: TikTok Ads tools
    name: tiktok-ads
paths:
  /api/v1/tools/update_meta_ad_set/execute:
    post:
      tags:
        - meta-ads
      summary: Update Meta Ad Set
      description: >-
        User wants to edit an existing Meta ad set's targeting, budget, bid,
        placements, schedule, or optimization settings.


        IMPORTANT: This tool modifies REAL ad sets in Meta Ads Manager. Changes
        take effect immediately.


        This is the primary tool for:

        - Changing audience targeting (age, gender, interests, locations)

        - Excluding placements (e.g., remove Audience Network)

        - Adjusting budgets at the ad set level

        - Changing bid amounts

        - Pausing/resuming specific ad sets

        - Modifying optimization goals


        Returns:

        - Confirmation of updates applied

        - Summary of all changes made

        - Ads Manager URL for the ad set


        When to use this tool:

        - "Change the targeting on my ad set"

        - "Exclude Audience Network from placements"

        - "Update the budget on this ad set to $50/day"

        - "Pause this ad set"

        - "Change the age range to 25-45"

        - "Add interest targeting for fitness"

        - "Exclude custom audience from this ad set"

        - "Change bid to $5"

        - "Update the optimization goal"


        Parameters:

        - ad_set_id: The Meta Ad Set ID to update (required)

        - status: ACTIVE, PAUSED, DELETED, ARCHIVED (optional)

        - name: New ad set name (optional)

        - daily_budget: New daily budget in USD (optional, min $1). DO NOT use
        for CBO campaigns.

        - lifetime_budget: New lifetime budget in USD (optional). DO NOT use for
        CBO campaigns.

        - daily_min_spend_target: CBO only — minimum daily spend for this ad set
        (use INSTEAD of daily_budget)

        - daily_spend_cap: CBO only — maximum daily spend cap for this ad set
        (use INSTEAD of daily_budget)

        - lifetime_min_spend_target: CBO only — minimum lifetime spend (for
        lifetime budget CBO)

        - lifetime_spend_cap: CBO only — maximum lifetime spend cap (for
        lifetime budget CBO)

        - bid_amount: New bid amount in USD (optional)

        - targeting: New targeting spec as JSON (optional) — for placements,
        audiences, demographics

        - start_time: New start time ISO format (optional)

        - end_time: New end time ISO format (optional)

        - optimization_goal: REACH, LINK_CLICKS, LANDING_PAGE_VIEWS,
        OFFSITE_CONVERSIONS, VALUE, etc. (optional)


        **CBO (Advantage Campaign Budget) campaigns:**

        For ad sets under CBO campaigns, do NOT set daily_budget or
        lifetime_budget.

        Use daily_min_spend_target / daily_spend_cap to control spend
        distribution.

        Setting daily_budget on a CBO ad set will cause Meta to reject with an
        error.


        At least one update field must be provided.


        Targeting Spec Examples:


        *Exclude Audience Network:*

        ```json

        {
          "publisher_platforms": ["facebook", "instagram"],
          "facebook_positions": ["feed", "stories", "reels"],
          "instagram_positions": ["stream", "story", "reels"]
        }

        ```


        *Change age and gender:*

        ```json

        {
          "age_min": 25,
          "age_max": 45,
          "genders": [1]
        }

        ```

        (genders: 1=male, 2=female, omit for all)


        *Add interest targeting:*

        ```json

        {
          "flexible_spec": [{"interests": [{"id": "6003139266461", "name": "Fitness"}]}]
        }

        ```


        *Exclude custom audience:*

        ```json

        {
          "excluded_custom_audiences": [{"id": "AUDIENCE_ID"}]
        }

        ```


        Execution time: 2-5 seconds

        Modifies: Real ad set in Meta Ads


        Workflow:

        1. Use `list_meta_ad_sets` or `get_meta_campaign_details` to find the ad
        set ID

        2. Use `update_meta_ad_set` with the changes you want to make

        3. Verify changes in Ads Manager
      operationId: execute_update_meta_ad_set
      parameters:
        - description: >-
            Client-generated UUID to make writes idempotent. Strongly
            recommended for write tools. A repeat call with the same key returns
            the cached result instead of re-executing. Example:
            550e8400-e29b-41d4-a716-446655440000
          example: 550e8400-e29b-41d4-a716-446655440000
          in: header
          name: Idempotency-Key
          required: false
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            example:
              arguments:
                ad_set_id: string
                bid_amount: 0.01
                daily_budget: 1
                lifetime_budget: 1
                name: string
                status: string
                targeting:
                  age_max: 55
                  age_min: 25
                  genders:
                    - 1
                    - 2
                  geo_locations:
                    countries:
                      - US
                  interests:
                    - id: '6003107902433'
                      name: Fitness and wellness
            schema:
              properties:
                arguments:
                  description: Input schema for updating a Meta ad set
                  properties:
                    ad_account_id:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: >-
                        Meta Ad Account ID. Required for multi-account users.
                        Get from list_connected_accounts.
                      title: Ad Account Id
                    ad_set_id:
                      description: The Meta Ad Set ID to update (required)
                      title: Ad Set Id
                      type: string
                    bid_amount:
                      anyOf:
                        - minimum: 0.01
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        New bid amount in USD. Will be converted to cents for
                        Meta API.
                      title: Bid Amount
                    daily_budget:
                      anyOf:
                        - minimum: 1
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        New daily budget in USD (minimum $1). Will be converted
                        to cents for Meta API.
                      title: Daily Budget
                    daily_min_spend_target:
                      anyOf:
                        - minimum: 0
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        Minimum daily spend target in account currency for CBO
                        campaigns. Use this instead of daily_budget when the
                        campaign uses Advantage Campaign Budget. Set to 0 to
                        remove the minimum.
                      title: Daily Min Spend Target
                    daily_spend_cap:
                      anyOf:
                        - minimum: 0
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        Maximum daily spend cap in account currency for CBO
                        campaigns. Use this instead of daily_budget when the
                        campaign uses Advantage Campaign Budget. Set to 0 to
                        remove the cap.
                      title: Daily Spend Cap
                    end_time:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: New end time in ISO format YYYY-MM-DDTHH:MM:SS
                      title: End Time
                    lifetime_budget:
                      anyOf:
                        - minimum: 1
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        New lifetime budget in USD. Will be converted to cents
                        for Meta API.
                      title: Lifetime Budget
                    lifetime_min_spend_target:
                      anyOf:
                        - minimum: 0
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        Minimum lifetime spend target in account currency for
                        CBO campaigns with lifetime budget.
                      title: Lifetime Min Spend Target
                    lifetime_spend_cap:
                      anyOf:
                        - minimum: 0
                          type: number
                        - type: 'null'
                      default: null
                      description: >-
                        Maximum lifetime spend cap in account currency for CBO
                        campaigns with lifetime budget.
                      title: Lifetime Spend Cap
                    name:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: New ad set name
                      title: Name
                    optimization_goal:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: >-
                        New optimization goal: REACH, IMPRESSIONS, LINK_CLICKS,
                        LANDING_PAGE_VIEWS, OFFSITE_CONVERSIONS, VALUE, etc.
                      title: Optimization Goal
                    start_time:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: New start time in ISO format YYYY-MM-DDTHH:MM:SS
                      title: Start Time
                    status:
                      anyOf:
                        - type: string
                        - type: 'null'
                      default: null
                      description: 'New status: ''ACTIVE'', ''PAUSED'', ''DELETED'', ''ARCHIVED'''
                      title: Status
                    targeting:
                      anyOf:
                        - additionalProperties: true
                          type: object
                        - type: 'null'
                      default: null
                      description: >-
                        New targeting specification as a JSON object. Use this
                        for placement exclusions, audience exclusions,
                        age/gender changes, interest targeting updates, and
                        location targeting changes.
                      title: Targeting
                  required:
                    - ad_set_id
                  type: object
              required:
                - arguments
              type: object
        description: >-
          All tool arguments are wrapped in an `arguments` object. The fields
          accepted inside `arguments` are listed below — required fields are
          marked with a red asterisk.
        required: true
      responses:
        '200':
          content:
            application/json:
              example:
                data:
                  quota:
                    limit: 150
                    period_end: '2026-05-01'
                    tier: plus
                    used: 42
                  text: (tool-specific textual output for update_meta_ad_set)
                success: true
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/SuccessResponse'
          description: >-
            Tool executed successfully. `data.text` carries the human-readable
            result (markdown-friendly). `data.quota` shows your current usage
            against the plan limit. `data.structured` appears when the tool
            emits machine-parseable structured content. `data.content` appears
            for tools that return non-text blocks (images, resources).
        '400':
          content:
            application/json:
              example:
                error: >-
                  You have 25 meta_ads accounts connected. Please specify which
                  account to use by passing the ad_account_id parameter:
                    - Acme Holdings (ad_account_id="act_123456789")
                    - Acme EU (ad_account_id="act_987654321")
                is_error: true
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            Tool-level error. The `error` string is safe to surface to end
            users. Common causes: missing required argument, multi-account user
            didn't specify which account, upstream platform validation failure.
        '401':
          content:
            application/json:
              example:
                error: >-
                  Not authenticated. Please connect your Adspirer account first
                  at https://adspirer.ai
                is_error: true
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Invalid, expired, or revoked API key.
        '402':
          content:
            application/json:
              example:
                error: |-
                  🚨 Monthly limit reached (150/150 tool calls on Plus tier).
                  Upgrade to Pro at https://adspirer.ai to keep building.
                is_error: true
                quota:
                  limit: 150
                  period_end: '2026-05-01'
                  tier: plus
                  upgrade_url: https://adspirer.ai
                  used: 150
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/QuotaErrorResponse'
          description: >-
            Quota exhausted for the current billing period. The response
            includes a `quota` block with the current used/limit/tier values and
            an `upgrade_url` to move up a tier.
        '404':
          content:
            application/json:
              example:
                error: 'Tool not found: update_meta_ad_set'
                is_error: true
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unknown tool_name. Check /openapi.json for the full catalog.
        '429':
          content:
            application/json:
              example:
                error: >-
                  Upstream platform rate limit hit (Meta Business Use Case
                  throttle at 95%). Retry after 60 seconds.
                is_error: true
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            Rate-limited by the upstream ad platform (Meta, Google, LinkedIn,
            TikTok). Retry with exponential backoff. Not the same as Adspirer's
            own quota — that returns 402.
        '500':
          content:
            application/json:
              example:
                error: 'Internal error: RuntimeError'
                is_error: true
                success: false
                tool: update_meta_ad_set
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            Unexpected server error. Report to support@adspirer.com with
            request_id.
      security:
        - ApiKeyAuth: []
components:
  schemas:
    SuccessResponse:
      description: >-
        Returned on HTTP 200. `data.text` is the primary human-readable output.
        `data.quota` is always present for billable calls. `data.structured` is
        set only when the tool emits machine-parseable structured content.
        `data.content` is set only when the tool emits non-text content blocks.
      properties:
        data:
          properties:
            content:
              description: Non-text content blocks (images, resources).
              items:
                $ref: '#/components/schemas/ContentBlock'
              type: array
            quota:
              $ref: '#/components/schemas/QuotaBlock'
            structured:
              additionalProperties: true
              description: >-
                Machine-parseable structured content when the tool provides it
                (e.g. account selection prompts, widget payloads).
              type: object
            text:
              description: >-
                Human-readable output. Markdown-friendly for tools that emit
                formatted lists, tables, or recommendations.
              type: string
          required:
            - text
          type: object
        success:
          const: true
          type: boolean
        tool:
          description: Echoed tool_name from the request URL.
          type: string
      required:
        - success
        - data
        - tool
      type: object
    ErrorResponse:
      description: >-
        Returned on HTTP 4xx / 5xx (except 402 which uses `QuotaErrorResponse`).
        `error` is always a human-readable string safe to surface to end users.
      properties:
        error:
          description: Human-readable error message.
          type: string
        is_error:
          const: true
          type: boolean
        structured_content:
          additionalProperties: true
          description: >-
            Present when the underlying tool attached structured metadata to the
            error (e.g. account-selection lists).
          type: object
        success:
          const: false
          type: boolean
        tool:
          type: string
      required:
        - success
        - error
        - tool
      type: object
    QuotaErrorResponse:
      description: >-
        Returned on HTTP 402 when the monthly quota is exhausted. Identical to
        `ErrorResponse` but with an additional `quota` block.
      properties:
        error:
          type: string
        is_error:
          const: true
          type: boolean
        quota:
          $ref: '#/components/schemas/QuotaBlock'
        success:
          const: false
          type: boolean
        tool:
          type: string
      required:
        - success
        - error
        - tool
        - quota
      type: object
    ContentBlock:
      additionalProperties: true
      description: >-
        A non-text content block. Rare today; tools that attach images,
        resources, or widget payloads populate `data.content` with blocks of
        this shape.
      properties:
        type:
          example: image
          type: string
      required:
        - type
      type: object
    QuotaBlock:
      description: >-
        Current quota state for the API key owner. Attached to every successful
        billable response under `data.quota`, and to 402 errors under `quota`
        (plus `upgrade_url`).
      properties:
        limit:
          description: Tool call allowance for the current tier.
          example: 150
          type: integer
        period_end:
          description: When the monthly counter resets (ISO date).
          example: '2026-05-01'
          format: date
          type: string
        tier:
          description: Subscription tier of the account that owns the API key.
          enum:
            - free
            - plus
            - pro
            - max
          example: plus
          type: string
        upgrade_url:
          description: Upgrade link (present only on 402 quota errors).
          format: uri
          type: string
        used:
          description: Tool calls consumed this billing period.
          example: 42
          type: integer
      required:
        - used
        - limit
        - tier
        - period_end
      type: object
  securitySchemes:
    ApiKeyAuth:
      bearerFormat: API Key (sk_live_...)
      description: >-
        API key from https://adspirer.ai/keys. Prefix `sk_live_`. Treat as a
        secret — never commit.
      scheme: bearer
      type: http

````